Les closures en PHP (Partie 1)

logo_php

Les closures, mais qu’est-ce que c’est ?

Une closure est simplement une fonction anonyme. Cette notion de closure est apparue dans la version 5.3 de php.

Voici un exemple :

function(){
    echo ‘je suis une closure’ ;
}

Vous l’aurez remarqué une closure a la particularité de ne pas être nommée.

Executons ce code :

$var = function(){

echo ‘que suis-je ?’ ;

}
var_dump($var) ;

Résultat :

object(Closure)#1 (0) { }

Vous l’avez bien compris il s’agit tout simplement d’un objet de type Closure qui dispose de la méthode magique __invoke.

Mais dans quel cas l’utiliser ?

Notez que les closures sont utilisées en grande partie en tant que fonctions de rappel. Celles-ci permettent d’exécuter du code défini dans une autre fonction.

Exemple avec la fonction array_map :

$bonjour = function($name){

return ‘Bonjour ‘. $name.’<br>’ ;

}

$name = array(‘Laurent’, ‘Herve’, ‘David’, ‘Matthieu’);

$name = array_map($bonjour, $name);

var_dump($name);

 

Résultat :

array(4) { [0]=> string(18) "Bonjour Laurent
" [1]=> string(17) "Bonjour Herve
" [2]=> string(19) "Bonjour David
" [3]=> string(17) "Bonjour Matthieu
" }

Vous l’avez compris array_map prend en 1er argument la fonction à appeler  (ici $bonjour) et en 2eme argument le tableau d’éléments sur lesquels appliquer cette fonction.

Je vous l’accorde, il s’agit d’un simple exemple mais allons un peu plus loin avec cette notion de closure.

Dans notre exemple ci-dessus, nous voudrions rendre dynamique le texte, tantôt avoir ‘Bonjour PRENOM’ ou ‘Au revoir PRENOM’,  à ce stade nous ne le pouvons pas car le texte ‘Bonjour’ est dans la définition de notre closure.

Ne me dites pas on va créer une autre closure ! Cette solution n’est pas maintenable ni performante et très coûteuse car si nous avons 100 textes différents nous allons avoir autant de closure, pour cela nous allons utiliser les variables extérieures.

L’utilisation de use :

Ce mot-clé permet d’attacher une variable à une closure.

Exemple :

$texte = ‘Bonjour’;

$bonjour = function($name) use ($texte){

return $texte.’ ‘. $name.’<br>’ ;

}

$name = array(‘Laurent’, ‘Herve’, ‘David’, ‘Matthieu’);

$name = array_map($bonjour, $name);

Ce code ne fait pas tout à fait ce que nous voulons car la variable est définie avant la closure et le code devra être dupliqué afin d’avoir un autre texte.

Mais quelle est donc la solution ?

Tout simplement en utilisant une fonction qui va se charger de renvoyer notre closure.

Voici le code :

function texteDuMoment($texte){

return function($name) use($texte){

return $texte. ‘ ‘.$name;

};

}

$name = array(‘Laurent’, ‘Herve’, ‘David’, ‘Matthieu’);

$name = array_map(texteDuMoment(‘Bonjour’), $name);

Nous aurons donc comme résultat : Bonjour Prénom…;

$name = array_map(texteDuMoment(‘Au revoir’), $name);

Nous aurons donc comme résultat : Au revoir Prénom….;

Détaillons rapidement ce code :

Nous passons à array_map en 1er argument la fonction texteDuMoment($texte) qui elle-même a comme argument le texte à envoyer. Ainsi la fonction texteDuMoment($texte) se charge d’appeler notre closure.

Bon à savoir :

Sachez également que nous pouvons également passer une closure comme argument à une fonction.

Même si la closure possède un argument sachez que nous n’aurons pas d’erreurs lors de l’appel de la closure sans passage de l’argument. En clair si l’argument est passé on l’utilisera dans le cas contraire aucune n’erreur ne sera levée contrairement à une fonction classique où nous aurions une belle notice avec le fameux message : undefined variable.

Pour conclure l’utilisation d’une closure est vraiment pratique pour créer des fonctions à la volée en manipulant des variables dans sa portée.

La 2eme partie de cet article traitera de l’utilisation d’une closure dans le contexte d’un objet.

Un commentaire

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.