Ich werde eine andere Frage mit dieser verknüpfen , weil ich versucht habe, eine Schließung zu nennen.
Akinuri
Antworten:
173
Das Handbuch verwendet die Begriffe "Rückruf" und "aufrufbar" synonym. "Rückruf" bezieht sich jedoch traditionell auf einen Zeichenfolgen- oder Arraywert, der wie ein Funktionszeiger fungiert und auf eine Funktion oder Klassenmethode für zukünftige Aufrufe verweist. Dies hat einige Elemente der funktionalen Programmierung seit PHP 4 ermöglicht. Die Aromen sind:
$cb1 ='someGlobalFunction';
$cb2 =['ClassName','someStaticMethod'];
$cb3 =[$object,'somePublicMethod'];// this syntax is callable since PHP 5.2.3 but a string containing it// cannot be called directly
$cb2 ='ClassName::someStaticMethod';
$cb2();// fatal error// legacy syntax for PHP 4
$cb3 = array(&$object,'somePublicMethod');
Dies ist eine sichere Methode, um aufrufbare Werte im Allgemeinen zu verwenden:
if(is_callable($cb2)){// Autoloading will be invoked to load the class "ClassName" if it's not// yet defined, and PHP will check that the class has a method// "someStaticMethod". Note that is_callable() will NOT verify that the// method can safely be executed in static context.
$returnValue = call_user_func($cb2, $arg1, $arg2);}
In modernen PHP-Versionen können die ersten drei oben genannten Formate direkt als aufgerufen werden $cb(). call_user_funcund call_user_func_arrayunterstütze alle oben genannten.
Wenn die Funktion / Klasse einen Namespace hat, muss die Zeichenfolge den vollständig qualifizierten Namen enthalten. Z.B['Vendor\Package\Foo', 'method']
call_user_funcunterstützt die Übergabe von Nichtobjekten als Referenz nicht, daher können Sie call_user_func_arrayden Rückruf entweder verwenden oder in späteren PHP-Versionen in einer Variablen speichern und die direkte Syntax verwenden : $cb();
Objekte mit einer __invoke()Methode (einschließlich anonymer Funktionen) fallen unter die Kategorie "aufrufbar" und können auf die gleiche Weise verwendet werden, aber ich persönlich verbinde diese nicht mit dem alten Begriff "Rückruf".
Das Erbe create_function()erstellt eine globale Funktion und gibt ihren Namen zurück. Es ist ein Wrapper für eval()und anonyme Funktionen sollten stattdessen verwendet werden.
In der Tat ist die Verwendung der Funktion der richtige Weg, dies zu tun. Wenn Sie eine Variable verwenden und sie dann einfach aufrufen, wie in der akzeptierten Antwort vorgeschlagen, ist dies cool, hässlich und lässt sich nicht gut mit Code skalieren.
icco
4
Akzeptierte Antwort geändert. Mit Kommentaren einverstanden, ist dies eine großartige Antwort.
Nick Stinemates
Für Leser aus der Python-Programmierung wäre es hilfreich, in der Antwort darauf hinzuweisen, dass es sich 'someGlobalFunction'tatsächlich um eine definierte Funktion handelt.
TMOTTM
1
Ab PHP 5.3 gibt es Schließungen, siehe Bart van Heukeloms Antwort . Es ist viel einfacher und "Standard" als all dieses alte Durcheinander.
wirklich schön
Ja, ich erwähne in meiner Antwort anonyme Funktionen, aber das OP hat nach "Rückruf" (2008) gefragt, und diese Rückrufe älteren Stils werden in Tonnen von PHP-Codebasen immer noch sehr häufig verwendet.
Steve Clay
74
Mit PHP 5.3 können Sie dies jetzt tun:
function doIt($callback){ $callback();}
doIt(function(){// this will be done});
Endlich ein schöner Weg, es zu tun. Eine großartige Ergänzung zu PHP, denn Rückrufe sind fantastisch.
Die Implementierung eines Rückrufs erfolgt auf diese Weise
// This function uses a callback function. function doIt($callback){
$data ="this is my data";
$callback($data);}// This is a sample callback function for doIt(). function myCallback($data){print'Data is: '. $data ."\n";}// Call doIt() and pass our sample callback function's name.
doIt('myCallback');
Oh mein Gott. Ist das der Standard? Das ist schrecklich!
Nick Retallack
Es gibt einige andere Möglichkeiten, wie oben gezeigt. Ich dachte wirklich das gleiche.
Nick Stinemates
3
@ Nick Retallack, ich sehe nicht, was daran so schrecklich ist. Für die mir bekannten Sprachen wie JavaScript und C # können alle ihre Rückruffunktion in einem solchen Muster strukturieren. Ich komme aus JavaScirpt und C # und bin es wirklich nicht gewohnt ,_user_func () aufzurufen. Ich habe das Gefühl, dass ich mich an PHP anpassen muss, anstatt umgekehrt.
Antony
4
@Antony Ich habe Einwände gegen die Tatsache erhoben, dass Strings Funktionszeiger in dieser Sprache sind. Ich habe diesen Kommentar vor drei Jahren gepostet, daher bin ich mittlerweile ziemlich daran gewöhnt, aber ich denke, PHP ist die einzige mir bekannte Sprache (außer Shell-Scripting), in der dies der Fall ist.
Nick Retallack
1
@Antony Ich bevorzuge die gleiche Syntax wie in Javascript. Ich verstehe also nicht einmal, warum Leute verwenden wollen, call_user_func()wenn sie eine Syntax haben, die es ihnen ermöglicht, Funktionen dynamisch aufzurufen und Rückrufe zu tätigen. Ich stimme mit Ihnen ein!
Botenvouwer
9
Ein raffinierter Trick, den ich kürzlich gefunden habe, ist die Verwendung von PHPs create_function(), um eine anonyme / Lambda-Funktion für die einmalige Verwendung zu erstellen. Es ist nützlich für die PHP - Funktionen wie array_map(), preg_replace_callback()oder usort()dass die Verwendung Rückrufe für benutzerdefinierte Verarbeitung. Es sieht ziemlich ähnlich aus wie eval()unter der Decke, aber es ist immer noch eine nette funktionale Art, PHP zu verwenden.
Leider spielt der Garbage Collector mit diesem Konstrukt nicht sehr gut, was zu potenziellen Speicherlecks führt. Wenn Sie keine Leistung erbringen möchten, vermeiden Sie create_function ().
Fuxia
1
Autsch. Danke für die Warnung.
Yukondude
Würde es Ihnen etwas ausmachen, die Antwort mit der PHP 7.4-Version (Pfeilfunktionen) zu aktualisieren und eine Warnung über veraltete create_function()Elemente hinzuzufügen ?
Dharman
7
Nun ... mit 5.3 am Horizont wird alles besser, denn mit 5.3 erhalten wir Schließungen und mit ihnen anonyme Funktionen
Sie möchten überprüfen, ob Ihr Anruf gültig ist. Im Fall einer bestimmten Funktion möchten Sie beispielsweise überprüfen, ob die Funktion vorhanden ist:
function doIt($callback){if(function_exists($callback)){
$callback();}else{// some error handling}}
Was ist, wenn Callback keine Funktion ist, sondern ein Array, das Objekt und Methode enthält?
d -_- b
3
oder besser gesagtis_callable( $callback )
Roko C. Buljan
1
Beides sind gute Vorschläge. Sie müssen Ihre eigene Implementierung überprüfen, wie Sie einen Rückruf durchführen. Ich hatte gehofft, davor zu warnen, etwas anzurufen, das es nicht gab und das tödlich war. Ich machte die Antwort allgemeiner
SeanDowney
5
create_functionhat in einer Klasse nicht für mich gearbeitet. Ich musste benutzencall_user_func .
Benötigt die Dispatcher-Klasse kein Attribut, damit $ this-> callback = $ callback funktioniert?
James P.
@ James Poulson: PHP ist eine dynamische Sprache, also funktioniert es. Aber ich war faul. Normalerweise erkläre ich Eigenschaften, die jedem das Leben erleichtern. Ihre Frage hat mich dazu gebracht, diesen Code noch einmal zu betrachten und einen Syntaxfehler zu entdecken, du. Danke
Goliatone
Ich wusste nicht, dass das möglich ist. Danke für die Antwort :) .
James P.
Wäre es nicht sicherer, die Funktion do_callback zu deklarieren, bevor das Dispatcher-Objekt erstellt und die asynchrone Methode aufgerufen wird?
Ejectamenta
3
Ich erschrecke jedes Mal, wenn ich create_function()in PHP benutze .
Parameter sind eine durch Koma getrennte Zeichenfolge, der gesamte Funktionskörper in einer Zeichenfolge ... Argh ... Ich denke, sie hätten es nicht hässlicher machen können, selbst wenn sie es versucht hätten.
Leider ist es die einzige Wahl, wenn eine benannte Funktion erstellt wird, die Mühe nicht wert ist.
Und natürlich ist es eine Laufzeit-String-Auswertung, sodass sie beim Kompilieren nicht auf gültige Syntax oder irgendetwas anderes überprüft wird.
Hobbs
Diese Antwort ist seit 2 Jahren veraltet. create_function()ist jetzt veraltet und sollte nicht verwendet werden.
Dharman
2
Für diejenigen, denen es nicht wichtig ist, die Kompatibilität mit PHP zu beeinträchtigen < 5.4, würde ich die Verwendung von Typhinweisen empfehlen, um eine sauberere Implementierung zu erzielen.
function call_with_hello_and_append_world( callable $callback ){// No need to check $closure because of the type hintreturn $callback("hello")."world";}function append_space( $string ){return $string." ";}
$output1 = call_with_hello_and_append_world(function( $string ){return $string." ";});
var_dump( $output1 );// string(11) "hello world"
$output2 = call_with_hello_and_append_world("append_space");
var_dump( $output2 );// string(11) "hello world"
$old_lambda = create_function('$string','return $string." ";');
$output3 = call_with_hello_and_append_world( $old_lambda );
var_dump( $output3 );// string(11) "hello world"
Antworten:
Das Handbuch verwendet die Begriffe "Rückruf" und "aufrufbar" synonym. "Rückruf" bezieht sich jedoch traditionell auf einen Zeichenfolgen- oder Arraywert, der wie ein Funktionszeiger fungiert und auf eine Funktion oder Klassenmethode für zukünftige Aufrufe verweist. Dies hat einige Elemente der funktionalen Programmierung seit PHP 4 ermöglicht. Die Aromen sind:
Dies ist eine sichere Methode, um aufrufbare Werte im Allgemeinen zu verwenden:
In modernen PHP-Versionen können die ersten drei oben genannten Formate direkt als aufgerufen werden
$cb()
.call_user_func
undcall_user_func_array
unterstütze alle oben genannten.Siehe: http://php.net/manual/en/language.types.callable.php
Anmerkungen / Vorsichtsmaßnahmen:
['Vendor\Package\Foo', 'method']
call_user_func
unterstützt die Übergabe von Nichtobjekten als Referenz nicht, daher können Siecall_user_func_array
den Rückruf entweder verwenden oder in späteren PHP-Versionen in einer Variablen speichern und die direkte Syntax verwenden :$cb()
;__invoke()
Methode (einschließlich anonymer Funktionen) fallen unter die Kategorie "aufrufbar" und können auf die gleiche Weise verwendet werden, aber ich persönlich verbinde diese nicht mit dem alten Begriff "Rückruf".create_function()
erstellt eine globale Funktion und gibt ihren Namen zurück. Es ist ein Wrapper füreval()
und anonyme Funktionen sollten stattdessen verwendet werden.quelle
'someGlobalFunction'
tatsächlich um eine definierte Funktion handelt.Mit PHP 5.3 können Sie dies jetzt tun:
Endlich ein schöner Weg, es zu tun. Eine großartige Ergänzung zu PHP, denn Rückrufe sind fantastisch.
quelle
Die Implementierung eines Rückrufs erfolgt auf diese Weise
Anzeigen: Daten sind: Dies sind meine Daten
quelle
call_user_func()
wenn sie eine Syntax haben, die es ihnen ermöglicht, Funktionen dynamisch aufzurufen und Rückrufe zu tätigen. Ich stimme mit Ihnen ein!Ein raffinierter Trick, den ich kürzlich gefunden habe, ist die Verwendung von PHPs
create_function()
, um eine anonyme / Lambda-Funktion für die einmalige Verwendung zu erstellen. Es ist nützlich für die PHP - Funktionen wiearray_map()
,preg_replace_callback()
oderusort()
dass die Verwendung Rückrufe für benutzerdefinierte Verarbeitung. Es sieht ziemlich ähnlich aus wieeval()
unter der Decke, aber es ist immer noch eine nette funktionale Art, PHP zu verwenden.quelle
create_function()
Elemente hinzuzufügen ?Nun ... mit 5.3 am Horizont wird alles besser, denn mit 5.3 erhalten wir Schließungen und mit ihnen anonyme Funktionen
http://wiki.php.net/rfc/closures
quelle
Sie möchten überprüfen, ob Ihr Anruf gültig ist. Im Fall einer bestimmten Funktion möchten Sie beispielsweise überprüfen, ob die Funktion vorhanden ist:
quelle
is_callable( $callback )
create_function
hat in einer Klasse nicht für mich gearbeitet. Ich musste benutzencall_user_func
.Dann zu verwenden:
[Bearbeiten] Eine fehlende Klammer wurde hinzugefügt. Außerdem habe ich die Rückrufdeklaration hinzugefügt, ich bevorzuge es so.
quelle
Ich erschrecke jedes Mal, wenn ich
create_function()
in PHP benutze .Parameter sind eine durch Koma getrennte Zeichenfolge, der gesamte Funktionskörper in einer Zeichenfolge ... Argh ... Ich denke, sie hätten es nicht hässlicher machen können, selbst wenn sie es versucht hätten.
Leider ist es die einzige Wahl, wenn eine benannte Funktion erstellt wird, die Mühe nicht wert ist.
quelle
create_function()
ist jetzt veraltet und sollte nicht verwendet werden.Für diejenigen, denen es nicht wichtig ist, die Kompatibilität mit PHP zu beeinträchtigen
< 5.4
, würde ich die Verwendung von Typhinweisen empfehlen, um eine sauberere Implementierung zu erzielen.quelle
create_function()
wurde ab PHP 7.2.0 VERRINGERT. Es wird dringend davon abgeraten, sich auf diese Funktion zu verlassen.