L'appel de fermeture assigné à la propriété de l'objet directement
Je voudrais être en mesure d'appeler une fermeture que j'attribue à une propriété de l'objet directement, sans réaffectation des de la fermeture pour une variable, puis en l'appelant. Est-ce possible?
Le code ci-dessous ne fonctionne pas et provoque Fatal error: Call to undefined method stdClass::callback()
.
$obj = new stdClass();
$obj->callback = function() {
print "HelloWorld!";
};
$obj->callback();
C'est exactement ce dont vous avez besoin: github.com/ptrofimov/jslikeobject Encore plus: vous pouvez utiliser $this à l'intérieur de fermetures et d'utiliser l'héritage. Seulement PHP>=5.4!
OriginalL'auteur Kendall Hopkins | 2010-12-26
Vous devez vous connecter pour publier un commentaire.
De PHP7, vous pouvez le faire
ou de l'utilisation Fermeture::call(), si cela ne fonctionne pas sur un
StdClass
.Avant PHP7, vous auriez à mettre en œuvre la magie
__call
méthode pour intercepter l'appel et appeler la fonction de rappel (qui n'est pas possible pourStdClass
bien sûr, parce que vous ne pouvez pas ajouter le__call
méthode)Notez que vous ne pouvez pas faire
dans le
__call
corps, car cela déclencherait__call
dans une boucle infinie.Cette syntaxe pour PHP7 est tout simplement merveilleux! MERCI
OriginalL'auteur Gordon
Vous pouvez le faire en appelant __invoke sur la fermeture, puisque c'est la magie de la méthode que des objets d'usage de se comporter comme des fonctions:
Bien sûr, cela ne fonctionnera pas si le rappel est un tableau ou une chaîne de caractères (qui peuvent aussi être valable rappels en PHP) - seulement pour les fermetures et autres objets avec d' __invoquer comportement.
très laid.
Je pense que c'est plus explicite que la accepté de répondre. Explicite est mieux dans ce cas. Si vous vous souciez vraiment pour un "mignon" de la solution,
call_user_func($obj->callback)
n'est pas si mauvais que ça.du point de vue sémantique, il n'a pas de sens d'avoir à faire
$obj->callback->__invoke();
quand on s'attend à être$obj->callback()
. C'est juste une question de cohérence.Certes, c'est pas cohérent. La cohérence n'a jamais vraiment été PHP fort, si. 🙂 Mais je pense qu'il n'a de sens, si l'on considère la nature de l'objet:
$obj->callback instanceof \Closure
.OriginalL'auteur Brilliand
De le PHP 7 vous pouvez effectuer les opérations suivantes:
OriginalL'auteur Korikulum
Il semble être possible, à l'aide de
call_user_func()
.pas élégant, mais.... Ce que @Gordon dit qu'il est probablement la seule façon d'aller.
OriginalL'auteur Pekka 웃
Bien, si vous vraiment insister. Une autre solution serait:
Mais ce n'est pas la plus belle de la syntaxe.
Cependant, l'analyseur PHP traite toujours
T_OBJECT_OPERATOR
,IDENTIFIER
,(
que l'appel de la méthode. Il semble y avoir aucune solution de contournement pour faire->
contourner la table de méthodes et d'accéder aux attributs de la place.OriginalL'auteur mario
Je sais que c'est vieux, mais je pense que les Traits de bien gérer ce problème si vous utilisez PHP 5.4+
Tout d'abord, créez un trait qui fait des propriétés appelable:
Ensuite, vous pouvez utiliser ce trait de caractère dans vos classes:
Maintenant, vous pouvez définir les propriétés via les fonctions anonymes et les appeler directement:
Merci :). Ce n'est probablement pas construit en raison de l'ambiguïté qu'il crée. Imaginez dans mon exemple, si il y avait effectivement une fonction appelée "ajouter" et une propriété appelée "ajouter". La présence de la parenthèse indique à PHP pour rechercher une fonction de même nom.
OriginalL'auteur SteveK
Depuis PHP 7 une clôture peut être appelée à l'aide de la
call()
méthode:Depuis PHP 7 est possible d'exécuter des opérations sur arbitraires
(...)
expressions trop (comme expliqué par Korikulum):Autres communes PHP 5 approches sont les suivantes:
à l'aide de la méthode magique
__invoke()
(comme expliqué par Brilliand)à l'aide de la
call_user_func()
fonctionà l'aide d'un variable intermédiaire dans une expression
Chacune a ses propres avantages et inconvénients, mais le changement le plus radical et définitif de la solution reste encore l'un présenté par Gordon.
OriginalL'auteur Daniele Orlando
Ici est une autre façon d'appeler correctement les propriétés de l'objet comme une fermeture.
Lorsque vous ne voulez pas changer l'objet de base utiliser ceci :
Mise à JOUR:
Call to undefined method AnyObject::callback()
(Classe AnyObject existe, bien sûr.)Il ne fonctionne pas. Sinon, il serait facile... 😀
Mise à jour du code du travail ok
Il fonctionne en PHP 5.3
OriginalL'auteur Mohamad Rostami
eh bien, il devrait être emphisized que le stockage de la fermeture dans une variable, et d'appeler la varible est en fait (wierdly) plus rapide, selon l'appel montant, il devient tout à fait un lot, avec xdebug (donc très précis de mesure), nous parlons de 1,5 (le facteur, en utilisant une varible, au lieu de directement de l'appel de la __invoke. donc , il suffit de stocker la fermeture d'une varible et de l'appeler.
OriginalL'auteur Kmtdk
Voici une autre alternative basée sur la accepté de répondre, mais qui s'étend stdClass directement:
Exemple d'utilisation:
Vous êtes probablement mieux d'utiliser
call_user_func
ou__invoke
.OriginalL'auteur Mahn
Si vous utilisez PHP 5.4 ou au-dessus, vous pouvez lier un objet appelable à la portée de votre objet pour invoquer un comportement personnalisé. Ainsi par exemple, si vous avez le jeu suivant..
Et vous étiez d'exploitation sur une classe comme si..
Vous pouvez exécuter votre propre logique, comme si vous étiez d'exploitation à partir de la portée de votre objet
OriginalL'auteur Lee Davis