Ich möchte in der Lage sein, einen Abschluss aufzurufen, den ich der Eigenschaft eines Objekts direkt zuweise, ohne den Abschluss einer Variablen neu zuzuweisen und ihn dann aufzurufen. Ist das möglich?
Der folgende Code funktioniert nicht und verursacht Fatal error: Call to undefined method stdClass::callback()
.
$obj = new stdClass();
$obj->callback = function() {
print "HelloWorld!";
};
$obj->callback();
php
object
properties
closures
Kendall Hopkins
quelle
quelle
Antworten:
Ab PHP7 können Sie dies tun
oder verwenden Sie Closure :: call () , obwohl dies bei a nicht funktioniert
StdClass
.Vor PHP7 müssten Sie die magische
__call
Methode implementieren , um den Aufruf abzufangen und den Rückruf aufzurufen (wasStdClass
natürlich nicht möglich ist , da Sie die__call
Methode nicht hinzufügen können ).Beachten Sie, dass Sie dies nicht tun können
im
__call
Körper, weil dies__call
in einer Endlosschleife auslösen würde .quelle
Sie können dies tun, indem Sie beim Schließen __invoke aufrufen, da dies die magische Methode ist, mit der sich Objekte wie Funktionen verhalten:
Das funktioniert natürlich nicht, wenn der Rückruf ein Array oder eine Zeichenfolge ist (was auch in PHP gültige Rückrufe sein können) - nur für Closures und andere Objekte mit __invoke-Verhalten.
quelle
call_user_func($obj->callback)
ist das nicht so schlimm.call_user_func
mit Saiten und das ist nicht immer praktisch$obj->callback->__invoke();
wann man es erwarten würde$obj->callback()
. Es ist nur eine Frage der Konsistenz.$obj->callback instanceof \Closure
.Ab PHP 7 können Sie Folgendes tun:
quelle
Seit PHP 7 kann ein Abschluss mit folgender
call()
Methode aufgerufen werden :Da PHP 7 auch Operationen mit beliebigen
(...)
Ausdrücken ausführen kann (wie von Korikulum erklärt ):Andere gängige PHP 5- Ansätze sind:
mit der magischen Methode
__invoke()
(wie von Brilliand erklärt )mit der
call_user_func()
FunktionVerwenden einer Zwischenvariablen in einem Ausdruck
Jeder Weg hat seine eigenen Vor- und Nachteile, aber die radikalste und endgültigste Lösung bleibt die von Gordon vorgestellte .
quelle
Es scheint möglich zu sein, mit
call_user_func()
.aber nicht elegant ... Was @Gordon sagt, ist wahrscheinlich der einzige Weg.
quelle
Nun, wenn Sie wirklich darauf bestehen. Eine weitere Problemumgehung wäre:
Aber das ist nicht die schönste Syntax.
Allerdings behandelt der PHP - Parser immer
T_OBJECT_OPERATOR
,IDENTIFIER
,(
als Methodenaufruf. Es scheint keine Problemumgehung zu geben,->
um die Methodentabelle zu umgehen und stattdessen auf die Attribute zuzugreifen.quelle
Ich weiß, dass dies alt ist, aber ich denke, dass Traits dieses Problem gut lösen, wenn Sie PHP 5.4+ verwenden
Erstellen Sie zunächst ein Merkmal, das Eigenschaften aufrufbar macht:
Dann können Sie dieses Merkmal in Ihren Klassen verwenden:
Jetzt können Sie Eigenschaften über anonyme Funktionen definieren und direkt aufrufen:
quelle
Nun, es sollte betont werden, dass das Speichern des Verschlusses in einer Variablen und das Aufrufen der Variablen tatsächlich (seltsam) schneller ist, abhängig von der Anrufmenge. Mit xdebug (so sehr genaues Messen) wird es ziemlich viel 1,5 (der Faktor, bei dem eine Variable verwendet wird, anstatt den __invoke direkt aufzurufen. Speichern Sie den Verschluss stattdessen einfach in einer Variablen und rufen Sie ihn auf.
quelle
Aktualisiert:
PHP> = 7:
PHP> = 5,4:
quelle
Call to undefined method AnyObject::callback()
(Klasse AnyObject existiert natürlich.)Hier ist eine weitere Alternative, die auf der akzeptierten Antwort basiert, aber stdClass direkt erweitert:
Anwendungsbeispiel:
Sie sind wahrscheinlich besser dran
call_user_func
oder__invoke
obwohl.quelle
Wenn Sie PHP 5.4 oder höher verwenden, können Sie einen Aufruf an den Bereich Ihres Objekts binden, um benutzerdefiniertes Verhalten aufzurufen. Wenn Sie zum Beispiel Folgendes einrichten möchten:
Und Sie haben an einer Klasse wie dieser gearbeitet.
Sie können Ihre eigene Logik ausführen, als würden Sie im Rahmen Ihres Objekts arbeiten
quelle
Ich stelle fest, dass dies in PHP5.5 funktioniert
Ermöglicht das Erstellen einer Pseudoobjektsammlung von Verschlüssen.
quelle