Maison >développement back-end >tutoriel php >Le noyau PHP propose des fonctions anonymes

Le noyau PHP propose des fonctions anonymes

藏色散人
藏色散人avant
2019-11-01 13:43:282781parcourir

Proposé

Avant l'émergence des fonctions anonymes, toutes les fonctions devaient être nommées avant de pouvoir être utilisées

function increment($value)
{
    return $value + 1;
}
array_map('increment', [1, 2, 3]);

Parfois, une fonction peut simplement devoir être utilisée Une fois. L'utilisation de fonctions anonymes rendra le code plus concis et intuitif, et empêchera également que la fonction soit utilisée ailleurs

array_map(function($value){
    return $value + 1;
}, [1, 2, 3]);

Définition et utilisation

PHP traite les fermetures et les anonymes. les fonctions sont des concepts équivalents (appelés collectivement fonctions anonymes dans cet article) et sont essentiellement des objets déguisés en fonctions.

L'essence des fonctions anonymes réside dans les objets, donc tout comme les objets, les fonctions anonymes peuvent être affectées à une variable

$greet = function(string $name){
    echo "hello {$name}";
}
$greet("jack") // hello jack

Toutes les fonctions anonymes sont des instances d'objets de fermeture

$greet instanceof Closure // true

Le L'objet n'a pas de portée parent, vous devez donc utiliser use pour déclarer manuellement les variables utilisées

$num = 1;
$func = function() use($num){
    $num = $num + 1;
    echo $num;
}
$func();  // 2
echo $num;  // 还是 1

Si vous souhaitez que les variables de la fonction anonyme prennent effet, vous devez utiliser le passage de référence. value

$num = 1;
$func = function() use(&$num){
    $num = $num + 1;
    echo $num;
}
$func();  // 2
echo $num;  // 2

À partir de PHP 5.4, lors de l'utilisation d'une fonction anonyme dans une classe, $this de la fonction anonyme sera automatiquement liée à la classe actuelle

class Foo {
    public function bar()
    {   
        return function() {
            return $this;
        };
    }
}
$foo = new Foo();
$obj = $foo->bar(); // Closure()
$obj();   // Foo

Si vous ne voulez pas que liaison automatique pour prendre effet, vous pouvez utiliser une fonction anonyme statique

class Foo {
    public function bar()
    {   
        return static function() {
            return $this;
        };
    }
}
$foo = new Foo();
$obj = $foo->bar(); // Closure()
$obj();   // Using $this when not in object context

L'essence des fonctions anonymes

L'essence des fonctions anonymes est l'objet Closure, qui comprend le suivant cinq méthodes

Closure {
    private __construct ( void )
    public static bind ( Closure $closure , object $newthis [, mixed $newscope = "static" ] ) : Closure
    public bindTo ( object $newthis [, mixed $newscope = "static" ] ) : Closure
    public call ( object $newthis [, mixed $... ] ) : mixed
    public static fromCallable ( callable $callable ) : Closure
}

__construct - Empêcher l'instanciation des fonctions anonymes

$closure = new \Closure();
// PHP Error:  Instantiation of 'Closure' is not allowed

Closure::bindTo - Copie l'objet de fonction anonyme actuel et lie l'objet $this et la portée de classe spécifiés. En termes simples, cela signifie lier manuellement une fonction anonyme à un objet spécifié. En utilisant cela, vous pouvez étendre les fonctionnalités de l'objet.

// 定义商品类
class Good {
    private $price;
    public function __construct(float $price)
    {
        $this->price = $price;
    }
}
// 定义一个匿名函数,计算商品的促销价
$addDiscount = function(float $discount = 0.8){
    return $this->price * $discount;
}
$good = new Good(100);
// 将匿名函数绑定到 $good 实例,同时指定作用域为 Good
$count = $addDiscount->bindTo($good, Good::class); 
$count(); // 80
// 将匿名函数绑定到 $good 实例,但是不指定作用域,将无法访问 $good 的私有属性
$count = $addDiscount->bindTo($good); 
$count(); // 报错

Closure::bind - une version statique de la méthode bindTo, avec deux utilisations :

Utilisation 1 : obtenir le même effet que la méthode bindTo

$count = \Closure::bind($addDiscount, $good, Good::class);

Utilisation 2 : Liez la fonction anonyme à la classe (plutôt qu'à l'objet). Pensez à définir le deuxième paramètre sur null

// 商品库存为 10
class Good {
    static $num = 10;
}
// 每次销售后返回当前库存
$sell = static function() {
    return"当前库存为". --static::$num ;
};
// 将静态匿名函数绑定到 Good 类中
$sold = \Closure::bind($sell, null, Good::class);
$sold(); // 当前库存为 9
$sold(); // 当前库存为 8

call - PHP 7 Nouveau. La méthode d'appel peut lier et appeler des fonctions anonymes. En plus d'une syntaxe plus simple, les performances sont également plus élevées

// call 版本
$addDiscount->call($good, 0.5);  // 绑定并传入参数 0.5,结果为 50
// bindTo 版本
$count = $addDiscount->bindTo($good, Good::class, 0.5); 
$count(); // 50

fromCallable - Convertit la fonction appelable donnée en une fonction anonyme

class Good {
    private $price;
    public function __construct(float $price)
    {
        $this->price = $price;
    }
}
function addDiscount(float $discount = 0.8){
    return $this->price * $discount;
}
$closure = \Closure::fromCallable('addDiscount');
$good = new Good(100);
$count = $closure->bindTo($good);  
$count = $closure->bindTo($good, Good::class);   // 报错,不能重复绑定作用域
$count(); // 报错,无法访问私有属性
<.>fromCallable est équivalent à

$reflexion = new ReflectionFunction(&#39;addDiscount&#39;);
$closure = $reflexion->getClosure();

Une chose qui nécessite une attention particulière ici est qu'il s'agisse de la fermeture convertie fromCallable ou de la fermeture obtenue par réflexion, lors de l'utilisation de bindTo, si la seconde Si le paramètre spécifie la classe de liaison , une erreur sera signalée

Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure()

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:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer