Come vengono scritti i callback in PHP?
Come vengono scritti i callback in PHP?
Risposte:
Il manuale usa i termini "callback" e "callable" in modo intercambiabile, tuttavia, "callback" si riferisce tradizionalmente a un valore di stringa o matrice che agisce come un puntatore a funzione , facendo riferimento a una funzione o a un metodo di classe per invocazioni future. Ciò ha consentito alcuni elementi di programmazione funzionale da PHP 4. I sapori sono:
$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');
Questo è un modo sicuro per utilizzare i valori richiamabili in generale:
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);
}
Le moderne versioni di PHP consentono di richiamare direttamente i primi tre formati sopra $cb(). call_user_funce call_user_func_arraysupporta tutto quanto sopra.
Vedi: http://php.net/manual/en/language.types.callable.php
Note / avvertimenti:
['Vendor\Package\Foo', 'method']call_user_funcnon supporta il passaggio non-oggetti con riferimento, in modo da poter usare sia call_user_func_arrayo, nelle versioni di PHP successive, Salva la richiamata ad una var e utilizzare la sintassi diretta: $cb();__invoke()metodo (comprese le funzioni anonime) rientrano nella categoria "richiamabile" e possono essere utilizzati allo stesso modo, ma personalmente non li associo al termine "callback" legacy.create_function()crea una funzione globale e restituisce il suo nome. È un wrapper per eval()e dovrebbero essere usate funzioni anonime.'someGlobalFunction'effetti è una funzione definita.
Con PHP 5.3, ora puoi farlo:
function doIt($callback) { $callback(); }
doIt(function() {
// this will be done
});
Finalmente un bel modo di farlo. Un'ottima aggiunta a PHP, perché i callback sono fantastici.
L'implementazione di un callback avviene in questo modo
// 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');
Visualizza: I dati sono: questi sono i miei dati
call_user_func()Quando hanno una sintassi che consente loro di chiamare dinamicamente le funzioni ed effettuare callback. Sono d'accordo con te!
Un trucco ingegnoso che ho trovato di recente è usare i PHP create_function()per creare una funzione anonima / lambda per l'uso one-shot. E 'utile per le funzioni PHP come array_map(), preg_replace_callback(), o usort()che utilizzano callback per l'elaborazione personalizzata. Sembra più o eval()meno un sottocoperta, ma è comunque un bel modo funzionale di usare PHP.
create_function()?
bene ... con 5.3 all'orizzonte, tutto andrà meglio, perché con 5.3 avremo chiusure e con loro funzioni anonime
Dovrai verificare qualunque sia la tua chiamata valida. Ad esempio, nel caso di una funzione specifica, dovrai verificare e vedere se la funzione esiste:
function doIt($callback) {
if(function_exists($callback)) {
$callback();
} else {
// some error handling
}
}
is_callable( $callback )
create_functionnon ha funzionato per me all'interno di una classe. Ho dovuto usare call_user_func.
<?php
class Dispatcher {
//Added explicit callback declaration.
var $callback;
public function Dispatcher( $callback ){
$this->callback = $callback;
}
public function asynchronous_method(){
//do asynch stuff, like fwrite...then, fire callback.
if ( isset( $this->callback ) ) {
if (function_exists( $this->callback )) call_user_func( $this->callback, "File done!" );
}
}
}
Quindi, per usare:
<?php
include_once('Dispatcher.php');
$d = new Dispatcher( 'do_callback' );
$d->asynchronous_method();
function do_callback( $data ){
print 'Data is: ' . $data . "\n";
}
?>
[Modifica] Aggiunta una parentesi mancante. Inoltre, ha aggiunto la dichiarazione di richiamata, la preferisco così.
Io rabbrividisco ogni volta che uso create_function()in php.
I parametri sono una stringa separata da coma, l'intero corpo della funzione in una stringa ... Argh ... Penso che non avrebbero potuto renderlo più brutto anche se ci avessero provato.
Sfortunatamente, è l'unica scelta quando la creazione di una funzione con nome non vale la pena.
create_function()è ora obsoleto e non deve essere utilizzato.
Per coloro che non si preoccupano di interrompere la compatibilità con PHP < 5.4, suggerirei di utilizzare il suggerimento sul tipo per realizzare un'implementazione più pulita.
function call_with_hello_and_append_world( callable $callback )
{
// No need to check $closure because of the type hint
return $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"
create_function() è stato DEPRECATO a partire da PHP 7.2.0. Affidarsi a questa funzione è altamente scoraggiato.