Je vérifie certaines PHP 5.3.0
fonctionnalités et j'ai parcouru du code sur le site qui a l'air assez drôle:
public function getTotal($tax)
{
$total = 0.00;
$callback =
/* This line here: */
function ($quantity, $product) use ($tax, &$total)
{
$pricePerItem = constant(__CLASS__ . "::PRICE_" .
strtoupper($product));
$total += ($pricePerItem * $quantity) * ($tax + 1.0);
};
array_walk($this->products, $callback);
return round($total, 2);
}
comme l'un des exemples de fonctions anonymes .
Quelqu'un le sait-il? Une documentation? Et il a l'air mauvais, devrait-il jamais être utilisé?
use
mot-clé est également utilisé pour aliaser les espaces de noms . Il est étonnant que, plus de 3 ans après la sortie de PHP 5.3.0, la syntaxefunction ... use
soit toujours officiellement non documentée, ce qui fait des fermetures une fonctionnalité non documentée. Le doc confond même les fonctions anonymes et les fermetures . La seule documentation (bêta et non officielle) sur queuse ()
j'ai pu trouver sur php.net était le RFC pour les fermetures .use
est également utilisé pour inclure untrait
dans unclass
!Une réponse plus simple.
function ($quantity) use ($tax, &$total) { .. };
$tax
à l'intérieur de la fermeture n'a aucun effet externe, sauf s'il s'agit d'un pointeur, comme un objet.&$total
. De cette façon, en modifiant la valeur de$total
DOES ONT un effet externe, la valeur de la variable d'origine change.Comme l'a souligné @Mytskine , la meilleure explication approfondie est probablement le RFC pour les fermetures . (Le voter pour cela.)
la source
$closure = function ($value) use ($localVar as $alias) { //stuff};
erreur donnée est:Parse: syntax error, unexpected 'as' (T_AS), expecting ',' or ')'
&$total
a également un effet interne. En d'autres termes, si vous modifiez la valeur de l'$total
extérieur de la fermeture après sa définition, la nouvelle valeur n'est transmise que s'il s'agit d'un pointeur.global
autorise uniquement l'accès à l'espace de noms global alors qu'iluse
autorise l'accès aux variables dans l'espace de noms parent. Les variables globales sont généralement considérées comme mauvaises. L'accès à la portée parent est souvent le but même de créer une fermeture. Ce n'est pas "mal" car sa portée est très limitée. D'autres langages comme JS utilisent implicitement les variables de la portée parent (comme pointeur, pas comme valeur copiée).You can pass in variables as pointers like in case of &$total. This way, modifying the value of $total DOES HAVE an external effect, the original variable's value changes.
le
function () use () {}
comme la fermeture de PHP.Sans
use
, la fonction ne peut pas accéder à la variable de portée parentLa
use
valeur de la variable est à partir du moment où la fonction est définie, pas lorsqu'elle est appeléeuse
référence par variable avec&
la source
les fermetures sont belles! ils résolvent beaucoup de problèmes qui viennent avec des fonctions anonymes et rendent possible un code vraiment élégant (au moins aussi longtemps que nous parlons de php).
les programmeurs javascript utilisent des fermetures tout le temps, parfois même sans le savoir, car les variables liées ne sont pas explicitement définies - c'est à cela que sert "utilisation" en php.
il y a de meilleurs exemples du monde réel que celui ci-dessus. disons que vous devez trier un tableau multidimensionnel par une sous-valeur, mais la clé change.
avertissement: code non testé (je n'ai pas php5.3 installé atm), mais il devrait ressembler à quelque chose comme ça.
il y a un inconvénient: beaucoup de développeurs php peuvent être un peu impuissants si vous les confrontez à des fermetures.
pour mieux comprendre la beauté des fermetures, je vais vous donner un autre exemple - cette fois en javascript. l'un des problèmes est la portée et l'asynchronité inhérente au navigateur. surtout s'il s'agit de
window.setTimeout();
(ou -interval). vous passez donc une fonction à setTimeout, mais vous ne pouvez pas vraiment donner de paramètres, car fournir des paramètres exécute le code!myFunction renvoie une fonction avec une sorte de paramètre prédéfini!
pour être honnête, j'aime beaucoup plus PHP depuis 5.3 et les fonctions / fermetures anonymes. les espaces de noms peuvent être plus importants, mais ils sont beaucoup moins sexy .
la source
Zupa a fait un excellent travail en expliquant les fermetures avec «utilisation» et la différence entre EarlyBinding et référencement des variables qui sont «utilisées».
J'ai donc fait un exemple de code avec liaison anticipée d'une variable (= copie):
Exemple de référencement d'une variable (notez le caractère '&' avant la variable);
la source
Jusqu'à très récemment, PHP a défini son AST et l'interpréteur PHP a isolé l'analyseur de la partie évaluation. Pendant le temps où la fermeture est introduite, l'analyseur PHP est fortement couplé avec l'évaluation.
Par conséquent, lorsque la fermeture a été introduite pour la première fois en PHP, l'interpréteur n'a aucune méthode pour savoir quelles variables seront utilisées dans la fermeture, car elle n'est pas encore analysée. L'utilisateur doit donc satisfaire le moteur zend par importation explicite, en faisant les devoirs que devrait faire zend.
Il s'agit de la méthode dite simple en PHP.
la source