Maison >développement back-end >tutoriel php >Fermeture PHP (Closure), explication détaillée d'exemples de fonctions anonymes

Fermeture PHP (Closure), explication détaillée d'exemples de fonctions anonymes

怪我咯
怪我咯original
2017-06-28 11:25:221056parcourir

Cet article vous présente principalement la fonction PHP anonyme introduite dans php5.3, qui est la fermeture (Closure), et le rôle de la fermeture. Elle est très détaillée. Je la recommande aux amis dans le besoin. . eux.

La fermeture de PHP (Closure) est une fonction anonyme, introduite dans PHP5.3.

La syntaxe de la fermeture est très simple. Le seul mot-clé qui nécessite une attention particulière est use. Il s'agit de connecter la fermeture et les variables externes.

Le code est le suivant :

$a = function() use($b) {}

Un exemple simple est le suivant :

Le code est le suivant :

function callback($fun) {
$fun();
}
$msg = "Hello, everyone";
$fun = function () use($msg) {
print "This is a closure use string value, msg is: $msg. <br />/n";
};
$msg = "Hello, everybody";
callback($fun);

Résultat Il s'agit d'une valeur de chaîne d'utilisation de fermeture, le msg est : Bonjour à tous df250b2156c434f3390392d09b1c9563/n

Dans la nouvelle syntaxe de fermeture ouverte de PHP, nous utilisons use to use. la fermeture définition externe des variables. Ici, nous utilisons la variable externe $msg. Une fois définie, sa valeur est modifiée. Une fois la fermeture exécutée, la valeur d'origine est affichée. Pour les paramètres de type de base transmis par valeur, la valeur de la fermeture utilisée est déterminée lors de la création de la fermeture.

La petite application est la suivante :

Le code est le suivant :

/** 
 * 一个利用闭包的计数器产生器 
 * 这里其实借鉴的是python中介绍闭包时的例子... 
 * 我们可以这样考虑: 
 *      1. counter函数每次调用, 创建一个局部变量$counter, 初始化为1. 
 *      2. 然后创建一个闭包, 闭包产生了对局部变量$counter的引用. 
 *      3. 函数counter返回创建的闭包, 并销毁局部变量, 但此时有闭包对$counter的引用,  
 *          它并不会被回收, 因此, 我们可以这样理解, 被函数counter返回的闭包, 携带了一个游离态的 
 *          变量. 
 *      4. 由于每次调用counter都会创建独立的$counter和闭包, 因此返回的闭包相互之间是独立的. 
 *      5. 执行被返回的闭包, 对其携带的游离态变量自增并返回, 得到的就是一个计数器. 
 * 结论: 此函数可以用来生成相互独立的计数器. 
 */  
function counter() {  
    $counter = 1;  
    return function() use(&$counter) {return $counter ++;};  
}  
$counter1 = counter();  
$counter2 = counter();  
echo "counter1: " . $counter1() . "<br />/n";  
echo "counter1: " . $counter1() . "<br />/n";  
echo "counter1: " . $counter1() . "<br />/n";  
echo "counter1: " . $counter1() . "<br />/n";  
echo "counter2: " . $counter2() . "<br />/n";  
echo "counter2: " . $counter2() . "<br />/n";  
echo "counter2: " . $counter2() . "<br />/n";  
echo "counter2: " . $counter2() . "<br />/n";  
?>

La fonction de fermeture

1. Réduisez le code de la boucle foreach
Par exemple, l'exemple de code Cart

dans le manuel http://php.net/manual/ fr/functions.anonymous.php Comme suit :

<?php
// 一个基本的购物车,包括一些已经添加的商品和每种商品的数量。
// 其中有一个方法用来计算购物车中所有商品的总价格。该方法使用了一个closure作为
回调函数
。
class Cart
{
    const PRICE_BUTTER  = 1.00;
    const PRICE_MILK    = 3.00;
    const PRICE_EGGS    = 6.95;
    protected   $products = array();
    public function add($product, $quantity)
    {
        $this->products[$product] = $quantity;
    }
    public function getQuantity($product)
    {
        return isset($this->products[$product]) ? $this->products[$product] :
               FALSE;
    }
    public function getTotal($tax)
    {
        $total = 0.00;
        $callback =
            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);;
    }
}
$my_cart = new Cart;
// 往购物车里添加条目
$my_cart->add(&#39;butter&#39;, 1);
$my_cart->add(&#39;milk&#39;, 3);
$my_cart->add(&#39;eggs&#39;, 6);
// 打出出总价格,其中有 5% 的销售税.
print $my_cart->getTotal(0.05) . "\n";
// The result is 54.29
?>

Ici si on transforme la fonction getTotal, il faut utiliser foreach.

2. Réduire les paramètres de la fonction

Le code est le suivant :

function html($code , $id="", $class=""){
if ($id !== "") $id = " id = \"$id\"" ;
$class = ($class !== "")? " class =\"$class\">":">";
$open = "<$code$id$class";
$close = "</$code>";
return function ($inner = "") use ($open, $close){
return "$open$inner$close";
    };
}

Si on utilise la méthode habituelle, nous L'intérieur sera placé dans les paramètres de la fonction html, de sorte que qu'il s'agisse de lire ou d'utiliser le code, il est préférable d'utiliser des fermetures.

3. Débloquez la fonction récursive

Le code est le suivant :

<?php
$fib = function($n) use(&$fib) {
    if($n == 0 || $n == 1) return 1;
    return $fib($n - 1) + $fib($n - 2);
};
echo $fib(2) . "\n"; // 2
$lie = $fib;
$fib = function(){die(&#39;error&#39;);};//rewrite $fib variable 
echo $lie(5); // error   because $fib is referenced by closure

Notez que l'utilisation dans le La question ci-dessus utilise & , si vous n'utilisez pas & ici, une erreur se produira fib(n-1) ne peut pas trouver la fonction (le type de fib n'a pas été défini précédemment)

, vous devez donc le faire. utilisez

lorsque vous souhaitez utiliser une fermeture pour annuler la fonction de boucle

Le code est le suivant :

<?php
$recursive = function () use (&$recursive){
// The function is now available as $recursive
}

sous cette forme.

4. Retarder la liaison

Si vous devez retarder la liaison des variables utilisées, vous devez utiliser une référence, sinon une copie sera effectuée lors de la définition de la copie. en cours d'utilisation

Le code est le suivant :

<?php
$result = 0;
$one = function()
{
    var_dump($result);
};
$two = function() use ($result)
{
    var_dump($result);
};
$three = function() use (&$result)
{
    var_dump($result);
};
$result++;
$one();    // outputs NULL: $result is not in scope
$two();    // outputs int(0): $result was copied
$three();    // outputs int(1)

Utiliser des références ou ne pas utiliser de références signifie s'il faut attribuer une valeur lors de l'appel ou lors de la déclaration

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn