448 votes

En PHP 5.3.0, quelle est l'identifiant de la fonction "use"?

Je vérifie quelques fonctionnalités de php 5.3.0 et j'ai parcouru du code sur le site qui a l'air assez marrant:

 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 sur les exemples sur: http://www.php.net/manual/fr/functions.anonymous.php

Est-ce que quelqu'un sait à ce sujet? Toute documentation? Et ça a l'air diabolique, faut-il jamais l'utiliser?

511voto

zupa Points 2634

Une simple réponse.

function ($quantity) use ($tax, &$total) { .. };

  1. La fermeture est une fonction assignée à une variable, de sorte que vous pouvez passer autour
  2. Une fermeture est séparé de l'espace de noms, normalement, vous ne pouvez pas accéder aux variables définies à l'extérieur de cet espace de noms. De là vient l' usage de mots clés:
  3. utilisation vous permet d'accéder (utilisation) successives des variables à l'intérieur de la clôture.
  4. l'utilisation est la liaison anticipée. Cela signifie que les valeurs des variables sont COPIÉS sur la définition de la fermeture. Donc, la modification de dollars de l'impôt à l'intérieur de la fermeture n'a pas d'effet externe.
  5. Vous pouvez passer des variables en tant que pointeurs comme dans le cas de &$au total. De cette façon, la modification de la valeur de $le total N'ONT un effet externe, la variable d'origine de modifications de la valeur.
  6. Les Variables définies à l'intérieur de la clôture ne sont pas accessibles de l'extérieur de la fermeture.
  7. Les fermetures et les fonctions ont la même vitesse. Oui, vous pouvez les utiliser partout dans vos scripts.

@Mytskine souligné probablement la meilleure explication en profondeur est la RFC pour les fermetures. (Upvote pour cela.)

396voto

Andrew Hare Points 159332

C'est la façon dont PHP exprime une fermeture. Ce n'est pas mal du tout et en fait, il est assez puissant et utile.

Fondamentalement, ce que cela signifie, c'est que vous permettez à la fonction anonyme pour "capturer" des variables locales (dans ce cas, $tax et une référence à l' $total) à l'extérieur de la portée et de préserver leurs valeurs (ou, dans le cas d' $total de la référence à l' $total lui-même) que de l'état dans la fonction anonyme.

54voto

stefs Points 8257

les fermetures sont belles! ils résoudre beaucoup de problèmes qui viennent avec des fonctions anonymes, et de les rendre très élégant de code possible (au moins aussi longtemps que nous parlons de php).

les programmeurs javascript utilisation de fermetures de tous les temps, parfois même sans le savoir, parce que lié variables ne sont pas définies explicitement que "l'utilisation" est en php.

il y a de meilleurs exemples du monde réel que dans le cas précédent. disons que vous avez le tri d'un tableau multidimensionnel par une sous-valeur, mais les principaux changements.

<?php
    function generateComparisonFunctionForKey($key) {
        return function ($left, $right) use ($key) {
            if ($left[$key] == $right[$key])
                return 0;
            else
                return ($left[$key] < $right[$key]) ? -1 : 1;
        };
    }

    $myArray = array(
        array('name' => 'Alex', 'age' => 70),
        array('name' => 'Enrico', 'age' => 25)
    );

    $sortByName = generateComparisonFunctionForKey('name');
    $sortByAge  = generateComparisonFunctionForKey('age');

    usort($myArray, $sortByName);

    usort($myArray, $sortByAge);
?>

avertissement: le code non testé (je n'ai pas de php5.Installé 3 atm), mais ça devrait ressembler à quelque chose comme ça.

il y a un inconvénient: beaucoup de développeurs php peut être un peu impuissant si vous confronter à des fermetures.

pour comprendre le nice-ty de fermetures de plus, je vais vous donner un autre exemple, cette fois en javascript. l'un des problèmes est la détermination de la portée et le navigateur inhérente asynchronity. en particulier, si elle vient à l' window.setTimeout(); (ou intervalle). donc, vous passez d'une fonction à setTimeout, mais vous ne pouvez pas vraiment donner les paramètres, car fournir des paramètres exécute le code!

function getFunctionTextInASecond(value) {
    return function () {
        document.getElementsByName('body')[0].innerHTML = value; // "value" is the bound variable!
    }
}

var textToDisplay = prompt('text to show in a second', 'foo bar');

// this returns a function that sets the bodys innerHTML to the prompted value
var myFunction = getFunctionTextInASecond(textToDisplay);

window.setTimeout(myFunction, 1000);

myFunction retourne une fonction avec un type de paramètre prédéfini!

pour être honnête, j'aime le php beaucoup plus puisque 5.3 et les fonctions anonymes et les fermetures. les espaces de noms peuvent être plus importantes, mais ils sont beaucoup moins sexy.

-2voto

JMHeap Points 66

PHP a divers "usage", un pour l'aliasing / l'importation ( http://php.net/manual/en/language.namespaces.importing.php ) et un autre pour les fermetures.

C'est très déroutant.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X