Le noyau PHP propose des fonctions anonymes

藏色散人
Libérer: 2023-04-07 18:22:01
avant
2726 Les gens l'ont consulté

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]);
Copier après la connexion

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]);
Copier après la connexion

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
Copier après la connexion

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

$greet instanceof Closure // true
Copier après la connexion

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
Copier après la connexion

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
Copier après la connexion

À 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
Copier après la connexion

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
Copier après la connexion

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
}
Copier après la connexion

__construct - Empêcher l'instanciation des fonctions anonymes

$closure = new \Closure();
// PHP Error:  Instantiation of 'Closure' is not allowed
Copier après la connexion

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(); // 报错
Copier après la connexion

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);
Copier après la connexion

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
Copier après la connexion

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
Copier après la connexion

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(); // 报错,无法访问私有属性
Copier après la connexion
<. 🎜>fromCallable est équivalent à

$reflexion = new ReflectionFunction(&#39;addDiscount&#39;);
$closure = $reflexion->getClosure();
Copier après la connexion

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()
Copier après la connexion

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!

Étiquettes associées:
php
source:learnku.com
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal