Maison >développement back-end >tutoriel php >Introduction à la fermeture en php
Les fonctions de fermeture, anonymes, ont été introduites dans php5.3, également connues sous le nom de fonctions anonymes. Le sens littéral est une fonction sans nom défini. Par exemple, le code suivant (le nom du fichier est do.php)
<?phpfunction A() {return 100; };function B(Closure $callback) {return $callback(); }$a = B(A());print_r($a);//输出:Fatal error: Uncaught TypeError: Argument 1 passed to B() must be an instance of Closure, integer given, called in D:\web\test\do.php on line 11 and defined in D:\web\test\do.php:6 Stack trace: #0 D:\web\test\do.php(11): B(100) #1 {main} thrown in D:\web\test\do.php on line 6?>
A() ici ne peut jamais être utilisé comme paramètre de B, car A n'est pas un " fonction "anonyme".
Il devrait donc être modifié comme suit :
<?php$f = function () {return 100; };function B(Closure $callback) {return $callback(); }$a = B($f);print_r($a);//输出100
<?$func = function( $param ) {echo $param; };$func( 'hello word' );//输出:hello word
Mettre la fonction anonyme dans ordinaire Il est transmis en paramètre dans la fonction et peut également être renvoyé. Cela implémente une fermeture simple.
Je vais vous donner trois exemples ci-dessous :
<?php//例一 //在函数里定义一个匿名函数,并且调用它function printStr() {$func = function( $str ) {echo $str; };$func( ' hello my girlfriend ! ' ); } printStr();//输出 hello my girlfriend ! //例二 //在函数中把匿名函数返回,并且调用它function getPrintStrFunc() {$func = function( $str ) {echo $str; };return $func; }$printStrFunc = getPrintStrFunc();$printStrFunc( ' do you love me ? ' );//输出 do you love me ? //例三 //把匿名函数当做参数传递,并且调用它function callFunc( $func ) {$func( ' no!i hate you ' ); }$printStrFunc = function( $str ) {echo $str.'<br>'; }; callFunc( $printStrFunc );//也可以直接将匿名函数进行传递。如果你了解js,这种写法可能会很熟悉callFunc( function( $str ) {echo $str; //输出no!i hate you } );
Les fermetures peuvent enregistrer l'emplacement Certaines variables et valeurs du contexte du bloc de code. Par défaut en PHP, les fonctions anonymes ne peuvent pas appeler de variables de contexte dans le bloc de code où elles se trouvent, mais doivent utiliser le mot-clé use.
Prenons un autre exemple (enfin, je suis à court d'argent, je suis vulgaire) :
<?phpfunction getMoney() {$rmb = 1;$dollar = 8;$func = function() use ( $rmb ) {echo $rmb;echo $dollar; };$func(); } getMoney();//输出:1
Comme vous pouvez le constater, le dollar n'est pas dedans l'instruction use password, elle ne peut pas être obtenue dans cette fonction anonyme, alors faites attention à ce problème pendant le développement.
Certaines personnes peuvent se demander si les variables de contexte peuvent être modifiées dans les fonctions anonymes, mais j'ai trouvé que cela ne semble pas possible :
<?phpfunction getMoney() {$rmb = 1;$func = function() use ( $rmb ) {echo $rmb.'<br>';//把$rmb的值加1$rmb++; };$func();echo $rmb; } getMoney();//输出: //1 //1
Eh bien, il s'avère que l'utilisation Ce qui est référencé n'est qu'un clone de la variable. Mais que faire si je veux citer complètement la variable au lieu de la copier ? Pour obtenir cet effet, ajoutez simplement un symbole & avant la variable :
<?phpfunction getMoney() {$rmb = 1;$func = function() use ( &$rmb ) {echo $rmb.'<br>';//把$rmb的值加1$rmb++; };$func();echo $rmb; } getMoney();//输出: //1 //2
D'accord, donc anonyme La fonction peut alors référencer les variables de contexte. Si la fonction anonyme est renvoyée au monde extérieur, la fonction anonyme enregistrera les variables référencées par l'utilisation, mais le monde extérieur ne pourra pas obtenir ces variables. De cette façon, le concept de « fermeture » peut être plus clair.
Selon la description, changeons l'exemple ci-dessus :
<?phpfunction getMoneyFunc() {$rmb = 1;$func = function() use ( &$rmb ) {echo $rmb.'<br>';//把$rmb的值加1$rmb++; };return $func; }$getMoney = getMoneyFunc();$getMoney();$getMoney();$getMoney();//输出: //1 //2 //3
D'accord, tant pis, alors si nous voulons appeler une fonction anonyme dans une classe Woolen tissu? Accédez directement à la démo
<?phpclass A {public static function testA() {return function($i) { //返回匿名函数return $i+100; }; } }function B(Closure $callback) {return $callback(200); }$a = B(A::testA());print_r($a);//输出 300
où A::testA() renvoie une fonction sans nom.
La fermeture dans l'exemple ci-dessus n'est qu'une fonction anonyme globale. D'accord, nous voulons maintenant spécifier une classe pour avoir une fonction anonyme. On comprend également que la portée d'accès de cette fonction anonyme n'est plus globale, mais la portée d'accès d'une classe.
Ensuite, nous devons lier "une fonction anonyme à une classe".
<?phpclass A {public $base = 100; }class B {private $base = 1000; }$f = function () {return $this->base + 3; };$a = Closure::bind($f, new A);print_r($a());//输出 103echo PHP_EOL;$b = Closure::bind($f, new B , 'B');print_r($b());//输出1003
Dans l'exemple ci-dessus, fCecipersonneanonymenomlettrenuméro中monomimpairmerveilleux deAprès la liaison, c'est comme s'il existait une telle fonction dans A, mais que cette fonction soit publique ou privée, le dernier paramètre de bind indique cette fonction portée appelable. Vous avez vu bindTo ci-dessus, jetons un œil à l'introduction sur le site officiel Valeur de retour : Renvoie un nouvel objet Closure ou retour sur échec
Regardons un exemple pour approfondir notre compréhension :(PHP 5 >= 5.4.0, PHP 7)Closure::bind — 复制一个闭包,绑定指定的$this对象和类作用域。 说明 public static Closure Closure::bind ( Closure $closure , object $newthis [, mixed $newscope = 'static' ] ) 这个方法是 Closure::bindTo() 的静态版本。查看它的文档获取更多信息。 参数 closure 需要绑定的匿名函数。 newthis 需要绑定到匿名函数的对象,或者 NULL 创建未绑定的闭包。 newscope 想要绑定给闭包的类作用域,或者 'static' 表示不改变。如果传入一个对象,则使用这个对象的类型名。 类作用域用来决定在闭包中 $this 对象的 私有、保护方法 的可见性。(备注:可以传入类名或类的实例,默认值是 'static', 表示不改变。)
FALSE
Grâce aux exemples ci-dessus, il n'est en fait pas difficile de comprendre la liaison anonyme.... Nous examinons une démo étendue (introduisant des fonctionnalités de trait)
<?phpclass A {private static $sfoo = 1;private $ifoo = 2; }$cl1 = static function() {return A::$sfoo; };$cl2 = function() {return $this->ifoo; };$bcl1 = Closure::bind($cl1, null, 'A');$bcl2 = Closure::bind($cl2, new A(), 'A');echo $bcl1(), "\n";//输出 1echo $bcl2(), "\n";//输出 2
<?phpclass A {public $base = 100; }class B {private $base = 1000; }class C {private static $base = 10000; }$f = function () {return $this->base + 3; };$sf = static function() {return self::$base + 3; };$a = Closure::bind($f, new A);print_r($a());//这里输出103,绑定到A类echo PHP_EOL;$b = Closure::bind($f, new B , 'B');print_r($b());//这里输出1003,绑定到B类echo PHP_EOL;$c = $sf->bindTo(null, 'C'); //注意这里:使用变量#sf绑定到C类,默认第一个参数为nullprint_r($c());//这里输出10003
Remarque supplémentaire : les fermetures peuvent utiliser la touche USE pour connecter des variables externes.
Résumé : Les caractéristiques des fermetures PHP peuvent en fait permettre d'obtenir des fonctions similaires, voire plus puissantes, en utilisant CLASS, sans parler des fermetures de js. Nous ne pouvons qu'attendre avec impatience des améliorations dans la prise en charge des fermetures PHP à l'avenir. Cependant, les fonctions anonymes restent très utiles. Par exemple, lorsque vous utilisez des fonctions telles que preg_replace_callback, vous n'avez pas besoin de déclarer une fonction de rappel en externe. Une utilisation appropriée des fermetures peut rendre le code plus concis et raffiné.
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!