Maison > développement back-end > tutoriel php > php Closure crée une fonction anonyme

php Closure crée une fonction anonyme

怪我咯
Libérer: 2023-03-11 17:40:01
original
1192 Les gens l'ont consulté

La

Classe de fermeture

est une classe utilisée pour représenter des fonctions anonymes.

Les fonctions anonymes (introduites dans PHP 5.3) produisent des objets de ce type. Dans le passé, cette classe était considérée comme un détail d'implémentation, mais on peut désormais compter sur elle pour faire quelque chose. Depuis PHP 5.4,
cette classe est livrée avec des méthodes qui permettent plus de contrôle sur la fonction anonyme après sa création.

Cette classe ne peut pas être instanciée. Elle contient deux méthodes principales, toutes deux utilisées pour copier des fermetures, une statique et une dynamique. Ces deux méthodes difficiles à comprendre sont expliquées en détail. ci-dessous.

Closure::bind

public static Closure Closure::bind ( Closure $closure , object $newthis [, mixed $newscope = 'static' ] )

参数说明:
closure
需要绑定的匿名函数。

newthis
需要绑定到匿名函数的对象,或者 NULL 创建未绑定的闭包。

newscope
想要绑定给闭包的类作用域,或者 'static' 表示不改变。如果传入一个对象,则使用这个对象的类型名。 类作用域用来决定在闭包中 $this 对象的 
私有、保护方法 的可见性。 The class scope to which associate the closure is to be associated, or 'static' to keep the 
current one. If an object is given, the type of the object will be used instead. This determines the visibility of 
protected and private methods of the bound object.
Copier après la connexion

Ce qui précède est la définition de cette méthode. Le premier paramètre est facile à comprendre, c'est une fonction de fermeture ; paramètre Ce n'est pas facile à comprendre. Si la fermeture à copier contient $this, cet objet représente ce
$this Les modifications apportées à cet objet dans la fonction de fermeture resteront cohérentes une fois l'appel terminé, comme les modifications. . Un attribut ; le troisième paramètre n'est pas facile à comprendre. La description officielle n'est pas non plus claire. Avec les paramètres par défaut de
, il y aura des restrictions. accédez uniquement aux fonctions de l'attribut $this->. Si vous souhaitez accéder à l'attribut object $newthis, public doit être défini sur le nom de classe/l'instance de classe correspondante. Tout comme dans la classe, vous devez accéder à la protection de celui-ci. classe./Fonction d’attribut privé. protected/private
Exemple

Le code ci-dessus signalera une erreur
<?php
class T {
    private function show()
    {
        echo "我是T里面的私有函数:show\n";
    }

    protected  function who()
    {
        echo "我是T里面的保护函数:who\n";
    }

    public function name()
    {
        echo "我是T里面的公共函数:name\n";
    }
}

$test = new T();

$func = Closure::bind(function(){
    $this->who();
    $this->name();
    $this->show();
}, $test);

$func();
Copier après la connexion
. Ajoutez le troisième paramètre de liaison comme t<a href="http://www.php.cn/wiki/167.html" target="_blank">::class<p> ou Fatal error: Uncaught Error: Call to protected method T::who() from context &#39;Closure&#39;, chaque résultat sera affiché normalement. t<a href="http://www.php.cn/wiki/167.html" target="_blank">::class</a>new T()

Bien sûr, les fermetures peuvent également transmettre des paramètres
我是T里面的保护函数:who
我是T里面的公共函数:name
我是T里面的私有函数:show
Copier après la connexion

Le programme ci-dessus est le même que la fonction anonyme et n'a aucune dépendance sur aucun objet. Le programme ci-dessus affichera :
$test = new StdClass();
var_dump($test);

$func = Closure::bind(function($obj){
    $obj->name = "燕睿涛";
}, null);

$func($test);
var_dump($test);
Copier après la connexion

Il existe un autre exemple qui nécessite une explication particulière
object(stdClass)#1 (0) {
}
object(stdClass)#1 (1) {
  ["name"]=>
  string(9) "燕睿涛"
}
Copier après la connexion

Qu'est-ce qui sera généré dans la situation ci-dessus Oui, une erreur sera signalée, indiquant que l'attribut privé ne peut pas être ? accessible
<?php
class T {
    private function show()
    {
        echo "我是T里面的私有函数:show\n";
    }

    protected  function who()
    {
        echo "我是T里面的保护函数:who\n";
    }

    public function name()
    {
        echo "我是T里面的公共函数:name\n";
    }
}

$func = Closure::bind(function ($obj) {
    $obj->show();
}, null);

$test = new T();

$func($test);
Copier après la connexion
. À ce stade, ajoutez simplement le troisième paramètre. Après avoir vu que le troisième paramètre n'affecte pas seulement la portée de

, show peut également affecter la portée du paramètre. $this

Closure::bindTo

a des fonctions similaires à

, voici juste une autre forme, les deux sont bindTo et les paramètres sont plus petits que bind Sans le premier, 复制当前闭包对象,绑定指定的$this对象和类作用域。 est le même que les deux derniers. Bien sûr, une autre différence est que bind n'est pas une méthode statique, mais une méthode d'attribut qui n'existe que dans les fermetures.
bindToExemple

La sortie de la fonction ci-dessus est similaire à celle de
<?php
class T {
    private function show()
    {
        echo "我是T里面的私有函数:show\n";
    }

    protected  function who()
    {
        echo "我是T里面的保护函数:who\n";
    }

    public function name()
    {
        echo "我是T里面的公共函数:name\n";
    }
}

$func = function () {
    $this->show();
    $this->who();
    $this->name();
};

$funcNew = $func->bindTo(new T(), T::class);

$funcNew();
Copier après la connexion

bind

Une astuce
我是T里面的私有函数:show
我是T里面的保护函数:who
我是T里面的公共函数:name
Copier après la connexion

Cette fonction est généré en regardant composer Je l'ai rencontré lorsque

a chargé automatiquement le

code source Il est utilisé de manière assez spécifique dans composer

. Le code ci-dessus est assez particulier. Dans
// 文件autoload_real.php
call_user_func(\Composer\Autoload\ComposerStaticInit898ad46cb49e20577400c63254121bac::getInitializer($loader));

// 文件autoload_static.php
public static function getInitializer(ClassLoader $loader)
{
    return \Closure::bind(function () use ($loader) {
        $loader->prefixLengthsPsr4 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixLengthsPsr4;
        $loader->prefixDirsPsr4 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixDirsPsr4;
        $loader->prefixesPsr0 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixesPsr0;
        $loader->classMap = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$classMap;

    }, null, ClassLoader::class);
}
Copier après la connexion
, la première impression est que le mauvais paramètre est passé. En fait, ce n'est pas le cas. Cette fonction renverra un

objet. > est une fonction anonyme. Le paramètre final transmis est toujours de type call_user_func. Regardez à nouveau la fermeture renvoyée Closure qui est utilisée, qui est le pont reliant la fermeture et les variables externes.
Quant à la raison pour laquelle des paramètres ordinaires peuvent être transmis ici, c'est parce qu'en PHP5, les paramètres formels de l'objet et les paramètres réels pointent vers le même objet, et les modifications apportées à l'objet dans la fonction seront reflétées à l'extérieur de l'objet. callableuseDonc, vous pouvez faire ce qui précède, il existe également une autre façon

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:
source:php.cn
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