17/06/2011

Tour d'horizon des Callbacks en PHP

Je suis toujours étonné de voir de nombreux développeurs PHP, pourtant habitués à travailler avec des callbacks en JavaScript, connaître si peu voire pas du tout les callbacks PHP.

C'est pourquoi je vous propose aujourd'hui un petit rappel des callbacks en PHP :

Un callback, c'est quoi ? En un mot, Un callback est une référence vers un code exécutable.

L'utilisation de callbacks est très fréquente dans certains langages. Un exemple simple en JavaScript :

[javascript] example [/javascript]

La fonction doAnything() est un callback, qui sera exécuté à chaque clic sur le lien.

Création d'un callback en PHP

En PHP, les callbacks peuvent être définis de nombreuses manières :

Fonction anonyme

$callback = function() {
    echo "un callback dans une fonction anonyme";
};

Fonction existante

Les callbacks peuvent référer une fonction existante. Dans ce cas, on utilise le nom de la fonction comme callback :

$callback = 'maFonction';

Méthode de classe existante

De la même façon, on peut référer une méthode de classe, avec cette fois quelques subtilités :

$callback = array('NomDeLaClass','maMethode');

Equivaut à :

$obj = new NomDeLaClass;
$callback = array($obj,'maMethode');

Ou encore (méthode statique) :

$callback = array('NomDeLaClass::maMethodeStatique');

Cas particuliers

Pour accéder au parent de la classe actuelle, utilisez le mot clef "parent" de cette façon :

$callback = array('parent::maMethode');

et cela de la même façon pour self et static :

$callback = array('self::maMethode');
$callback = array('static::maMethode');

Appeler/Exécuter un callback

le plus simple est sans doute d'utiliser la fonction call_user_func :

call_user_func($callback);

le moins élégant (c'est le moins qu'on puisse dire :-)) est d'utiliser la syntaxe suivante :

$callback();

Passage de paramètres et références

Nous allons nous attarder maintenant sur les paramètres à passer au callback. C'est simple :

$callback($param1, $param2);
// ou
call_user_func($callback, $param1, $param2);

la fonction call_user_func a une soeur, call_user_func_array, qui permet de passer les paramètres sous forme de tableau :

call_user_func_array($callback, array($param1, $param2));

Jusque là, c'est simple. Il faut juste faire attention au passages de paramètres par référence. En effet, la fonction call_user_func() ne passe pas les paramètres par référence :

function test(&$val) {
}
call_user_func('test', $value);
// Warning: Parameter 1 to test()
// expected to be a reference, value given

Il faut ruser et passer par call_user_func_array() en forçant la référence :

function test(&$a) {
}
call_user_func_array('test',array(&$value));
// Cette fois c'est bon

Performances

Les appels de fonctions de type callback sont plus lents que des appels de fonction directs. Voici un bench sur 1 million d'itérations :

Bench Callbacks en PHP 5.3

Certes il y a une différence, mais dans application standard cette différence est généralement négligeable.

Le mot de la fin

Vous me direz que PHP n'est pas à la base un langage où l'utilisation massive des callbacks est pertinente. Mais bien utilisé, les callbacks peuvent significativement alléger le code, et en voici un exemple trivial :

$array=array('pomme','peche','poire','abricot');
array_walk($array, function(&$item) {
    $item = strtoupper($item);
});
print_r($array);
//Array
//(
//    [0] => POMME
//    [1] => PECHE
//    [2] => POIRE
//    [3] => ABRICOT
//)

Et vous, vous avez l'habitude d'utiliser des callbacks, ou bien vous réservez ça pour d'autres langages ?

blog comments powered by Disqus