Heim  >  Artikel  >  Backend-Entwicklung  >  Eine kurze Diskussion der PHP-Closure-Klasse und ihrer Verwendung

Eine kurze Diskussion der PHP-Closure-Klasse und ihrer Verwendung

青灯夜游
青灯夜游nach vorne
2021-03-05 17:58:414826Durchsuche

Dieser Artikel stellt Ihnen die PHP-Closure-Klasse vor und zeigt Ihnen, wie Sie mit Closure anonyme Funktionen erstellen. Es hat einen gewissen Referenzwert. Freunde in Not können sich darauf beziehen. Ich hoffe, es wird für alle hilfreich sein.

Eine kurze Diskussion der PHP-Closure-Klasse und ihrer Verwendung

Empfohlenes Lernen: „PHP-Video-Tutorial

Abschlussklasse

Eine Klasse zur Darstellung anonymer Funktionen.

Anonyme Funktionen (eingeführt in PHP 5.3) erzeugen Objekte dieses Typs. In der Vergangenheit galt diese Klasse als Implementierungsdetail, aber jetzt kann man sich darauf verlassen, dass sie etwas tut. Ab PHP 5.4 verfügt
Diese Klasse über Methoden, die eine bessere Kontrolle über die anonyme Funktion ermöglichen, nachdem sie erstellt wurde.

Diese Klasse kann nicht instanziiert werden. Sie enthält zwei Hauptmethoden, die beide zum Kopieren von Abschlüssen verwendet werden, eine statische und eine dynamische. Diese beiden schwer verständlichen Methoden werden im Folgenden ausführlich erläutert.

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.

Das Obige ist die Definition dieser Methode. Der erste Parameter ist leicht zu verstehen, wenn der zu kopierende Abschluss nicht leicht zu verstehen ist $this, dieses Objekt stellt dies dar $this,这个对象就表示这个
$this,闭包函数里面对这个对象的修改在调用结束之后也会保持一致,比如修改了一个属性;第三个参数就不太好理解了,看官方的说明也是云里雾里的,
默认参数情况下,调用$this->访问object $newthis中的属性函数的时候,会有限制,只能访问public属性的函数,如果想访问protected/private属性,
就要设置为对应的类名/类实例,就要像在类里面一样,要访问那个类的保护/私有属性函数。

例子

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

上面的代码会报错Fatal error: Uncaught Error: Call to protected method T::who() from  context 'Closure'。 加上bind第三个参数为t::class或者new T(),会正常输出每一个结果。

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

当然了,闭包也可以传递参数

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

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

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

上面的程序跟匿名函数一样,啥对象也没有依赖,上面的程序会输出:

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

另外还有个特别要说明的例子

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

上面的情况会输出什么呢,没错,会报错,提示访问不了私有属性show,这个时候,加上第三个参数就可以了,看了第三个参数不光影响$this的作用域,
也可以影响参数的作用域。

Closure::bindTo

bindTobind功能类似,这里只是另外一种形式,都是复制当前闭包对象,绑定指定的$this对象和类作用域。,参数比bind少了第一个,
后面两个一样,当然还有一个区别就是bindTo不是静态方法,是闭包才会存在的一个属性方法。

例子

<?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的类似

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

一个trick

这个函数是在看composer生成的自动加载源码的时候碰到的,在composer中用的比较特别,下面是截取部分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);
}

上面的代码比较奇特,在call_user_func中,第一感觉是传错参数了,其实不然,这里调用了一个函数,这个函数会返回一个Closure对象,
也就是一个匿名函数,最终传入的参数还是一个callable类型。再看看这个返回的闭包,里面使用了use$this Änderungen an diesem Objekt in der Abschlussfunktion bleiben nach Abschluss des Aufrufs konsistent, z. B. das Ändern eines Attributs Parameter ist nicht leicht zu verstehen.
Mit den Standardparametern rufen Sie $this-> auf, um auf object $newthis zuzugreifen code> gibt es Einschränkungen. Sie können nur auf Funktionen mit <code>public-Attributen zugreifen. Wenn Sie auf protected/private-Attribute zugreifen möchten, muss

auf den entsprechenden Klassennamen gesetzt sein /class-Instanz, genau wie in der Klasse, müssen Sie auf die geschützte/private Attributfunktion dieser Klasse zugreifen.

Beispiel

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);
}
Der obige Code meldet einen FehlerSchwerwiegender Fehler: Nicht erfasster Fehler: Aufruf der geschützten Methode T::who() aus dem Kontext „Closure“. Fügen Sie den dritten Parameter von bind zu <code>t::class oder new T() hinzu, und jedes Ergebnis wird normal ausgegeben. rrreeeNatürlich können Abschlüsse auch Parameter übergeben

rrreee

Das obige Programm ist das gleiche wie die anonyme Funktion und hat keine Abhängigkeiten von irgendwelchen Objekten. Das obige Programm gibt Folgendes aus: 🎜rrreee🎜Es gibt auch ein spezielles Beispiel, das dies tun muss erklärt werden🎜rrreee🎜 Was wird in der obigen Situation ausgegeben? Ja, es wird ein Fehler gemeldet, der darauf hinweist, dass auf die private Eigenschaft show nicht zugegriffen werden kann. Fügen Sie zu diesem Zeitpunkt einfach den dritten Parameter hinzu Beim Lesen des dritten Parameters wirkt sich dies nicht nur auf $this aus, 🎜 kann sich auch auf den Parameterumfang auswirken. 🎜

🎜Closure::bindTo🎜🎜🎜bindTo und bind haben ähnliche Funktionen, hier ist nur eine andere Form, beide kopieren The Das aktuelle Abschlussobjekt ist an das angegebene $this-Objekt und den angegebenen Klassenbereich gebunden. , der erste Parameter ist kleiner als bind und die letzten beiden sind gleich. Natürlich gibt es einen weiteren Unterschied: bindTo ist keine statische Methode. aber eine Schließung Es existiert eine Eigenschaftsmethode. 🎜

🎜Beispiel🎜

rrreee🎜Die Ausgabe der obigen Funktion ähnelt der von bind🎜rrreee

🎜ein Trick🎜 🎜🎜Diese Funktion wurde beim Betrachten des vom Composer generierten automatisch geladenen Quellcodes festgestellt. Sie wird in Composer auf besondere Weise verwendet. Das Folgende ist ein Abfangen eines Teils des Codes in Composer Code ist ziemlich seltsam, in call_user_func ist der erste Eindruck, dass dies nicht der Fall ist. Eine Funktion wird hier aufgerufen -Objekt, das ebenfalls eine anonyme Funktion ist. Die übergebenen Parameter sind schließlich auch ein aufrufbarer-Typ. Schauen Sie sich den zurückgegebenen Abschluss noch einmal an. Dies ist die Brücke, die den Abschluss und externe Variablen verbindet. 🎜Der Grund, warum hier normale Parameter übergeben werden können, liegt darin, dass in PHP5 die formalen Objektparameter und tatsächlichen Parameter auf dasselbe Objekt verweisen und Änderungen am Objekt in der Funktion außerhalb des Objekts widergespiegelt werden. 🎜🎜Also, es ist in Ordnung, das oben Gesagte zu tun, es gibt auch einen anderen Weg🎜rrreee🎜🎜Zusammenfassung🎜🎜🎜Ich habe schon lange nicht mehr gebloggt, manchmal bin ich zu gereizt und kann mich nicht beruhigen, manchmal Ich finde nichts, worüber du schreiben möchtest. Man muss sich trotzdem beruhigen, alles gut machen, sich nicht aufregen, wenn etwas passiert, einen offenen Geist bewahren und alles ruhig angehen. 🎜

Am Ende des Schreibens fiel mir plötzlich ein, dass es in der Zeit des Wenchuan-Erdbebens 5.12 Uhr war. Nach dem Erdbeben gab es sofort Nachbeben Wenn es Nachbeben gab, gerieten alle in Panik und strömten herbei, wenn ich mich recht erinnere, waren wir im 5. Stock. Dieser Lehrer war älter und ein Sonderlehrer in der Stadt Es sollte stimmen). Es gab ein Nachbeben, und alle waren wieder bereit, wegzulaufen. Zu diesem Zeitpunkt sagte der Lehrer etwas, das ich bis heute nicht vergessen werde Bei einem so kleinen Nachbeben ist die Wahrscheinlichkeit eines Unfalls höher. Obwohl dieser Satz ein wenig Negativität enthält, sind die meisten davon Ausdruck eines ruhigen Geistes, eines relativ großen Herzens sowie von Ruhe und Entschlossenheit lernen möchte.

Was erscheinen sollte, wird immer erscheinen, und was nicht erscheinen sollte, wird niemals erscheinen. Blindes Streben nach einem zu weiten Ziel kann leicht zu Ängsten führen. Mit einem Wort: Seien Sie ruhig Seien Sie aufgeschlossen und machen Sie sich keine Sorgen über Gewinne und Verluste. 命在骨子里,这种余震没必要这么慌挤下去,命硬的怎么都没事 Je härter Sie arbeiten, desto mehr Glück haben Sie.

Weitere Kenntnisse zum Thema Programmierung finden Sie unter:

Programmiervideos
! !

Das obige ist der detaillierte Inhalt vonEine kurze Diskussion der PHP-Closure-Klasse und ihrer Verwendung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:cnblogs.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen