Maison  >  Article  >  développement back-end  >  Une brève discussion sur la classe PHP Closure et son utilisation

Une brève discussion sur la classe PHP Closure et son utilisation

青灯夜游
青灯夜游avant
2021-03-05 17:58:414908parcourir

Cet article vous présentera la classe PHP Closure et comment utiliser Closure pour créer des fonctions anonymes. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. J'espère qu'il sera utile à tout le monde.

Une brève discussion sur la classe PHP Closure et son utilisation

Apprentissage recommandé : "Tutoriel vidéo PHP"

Cours de clôture

Pour classes qui représentent 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 ; non C'est facile à comprendre. Si la fermeture à copier contient $this, cet objet représente ceci
$this Les modifications apportées à cet objet dans la fonction de fermeture resteront cohérentes une fois l'appel terminé. Attributs ; 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 lors de l'appel de $this-> pour accéder aux fonctions d'attribut dans object $newthis , une fonction qui ne peut accéder qu'à elle. l'attribut public. Si vous souhaitez accéder à l'attribut protected/private,
doit être défini sur le nom de classe/l'instance de classe correspondante, et vous devez accéder à la protection/confidentialité de cette classe comme dans l'attribut de classe. fonction.

Exemple

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

Le code ci-dessus signalera une erreurFatal error: Uncaught Error: Call to protected method T::who() from  context 'Closure'. L'ajout du troisième paramètre de bind à t::class ou new T() affichera chaque résultat normalement.

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

Bien sûr, les fermetures peuvent également transmettre des paramètres

$test = new StdClass();
var_dump($test);

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

$func($test);
var_dump($test);

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 :

object(stdClass)#1 (0) {
}
object(stdClass)#1 (1) {
  ["name"]=>
  string(9) "燕睿涛"
}
.

Il y a aussi un exemple spécial qui doit être expliqué

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

Que sera le résultat dans la situation ci-dessus ? Oui, une erreur sera signalée, indiquant que l'attribut privé n'est pas accessible show. Pour le moment, ajoutez simplement le troisième paramètre. Oui, j'ai vu que le troisième paramètre affecte non seulement la portée de $this, mais
peut également affecter la portée des paramètres.

Closure::bindTo

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

Exemple

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

La sortie de la fonction ci-dessus est similaire à celle de bind

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

Une astuce

Cette fonction a été rencontrée en regardant le code source de chargement automatique généré par composer. Elle est utilisée d'une manière spéciale dans composer. Ce qui suit est une interception d'une partie du code dans composer

// 文件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);
}
Le code ci-dessus est assez étrange. Dans

, la première impression est que les mauvais paramètres sont passés. En fait, ce n'est pas le cas. Cette fonction renverra un objet call_user_func. 🎜> est une fonction anonyme. Le paramètre final transmis est toujours de type Closure. Regardez à nouveau la fermeture renvoyée
qui est utilisée, qui est le pont reliant la fermeture et les variables externes. callableQuant à 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. use
Donc, c'est bien de faire ce qui précède, il y a une autre façon aussi

call_user_func(\Composer\Autoload\ComposerStaticInit898ad46cb49e20577400c63254121bac::getInitializer(), $loader);

public static function getInitializer()
{
    return \Closure::bind(function ($loader) {
        $loader->prefixLengthsPsr4 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixLengthsPsr4;
        $loader->prefixDirsPsr4 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixDirsPsr4;
        $loader->prefixesPsr0 = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$prefixesPsr0;
        $loader->classMap = ComposerStaticInit25885cdf386fdaafc0bce14bb5a7d06e::$classMap;

    }, null, ClassLoader::class);
}

Résumé

Je n'ai pas blogué depuis longtemps Parfois Je suis trop agité et je n'arrive pas à me calmer, et parfois je ne trouve pas ce que je veux écrire. Il faut quand même se calmer, tout bien faire, ne pas s'agiter quand les choses arrivent, garder l'esprit ouvert et gérer tout sereinement.

À la fin de l'écriture, je me suis soudainement souvenu que lorsque j'étais au lycée, c'était l'époque du tremblement de terre de Wenchuan le 5.12. Nous étions à Xi'an. Après le tremblement de terre, il y aurait des répliques dès. s'il y avait des répliques, tout le monde paniquait et se précipitait, si je me souviens bien, nous étions au 5ème étage,
jusqu'à ce qu'un jour notre professeur de physique vienne en classe. Ce professeur était plus âgé et était un professeur spécial. la ville (enfin, ça devrait être vrai), et j'ai rencontré une réplique, tout le monde se préparait à sortir en courant comme un fou. À ce moment-là, le professeur a dit quelque chose que je n'oublierai jamais à ce jour. En effet, si vous introduisez une si petite réplique, cela peut être plus susceptible de provoquer un accident. Bien que cette phrase contienne un peu de négativité, il s'agit plutôt d'un esprit calme, d'un cœur plus grand et d'un calme et d'un esprit calme. réflexion décisive. C’est ce que je veux apprendre.
命在骨子里,这种余震没必要这么慌挤下去,命硬的怎么都没事Ce qui devrait apparaître apparaîtra toujours, et ce qui ne devrait pas apparaître n'apparaîtra jamais. Viser aveuglément trop haut et poursuivre un objectif trop loin peut facilement conduire à l'anxiété. Bien sûr, ne vous rabaissez pas. soyez calme, soyez magnanime et prévenant. Ne vous inquiétez pas des gains et des pertes
Faites tout bien de manière terre-à-terre. Plus vous travaillez dur, plus vous aurez de chance. , plus vous travaillez dur.

Pour plus de connaissances sur la programmation, veuillez visiter :
Vidéo de programmation

 ! !

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:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer