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

php Closure crée une fonction anonyme

怪我咯
怪我咯original
2017-06-28 11:22:451257parcourir

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.

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();
. Ajoutez le troisième paramètre de liaison comme t<a href="http://www.php.cn/wiki/167.html" target="_blank">::class<p></p></a> ou Fatal error: Uncaught Error: Call to protected method T::who() from  context 'Closure', 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

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);

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

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);
. À 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();

bind

Une astuce
我是T里面的私有函数:show
我是T里面的保护函数:who
我是T里面的公共函数:name

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);
}
, 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!

Déclaration:
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