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(); // 报错,无法访问私有属性
$reflexion = new ReflectionFunction('addDiscount'); $closure = $reflexion->getClosure();
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!