Heim  >  Artikel  >  Backend-Entwicklung  >  Einführung in den Abschluss in PHP

Einführung in den Abschluss in PHP

零下一度
零下一度Original
2017-06-23 14:24:401182Durchsuche

Closure, anonyme Funktionen, wurden in PHP5.3 eingeführt, auch bekannt als anonyme Funktionen. Die wörtliche Bedeutung ist eine Funktion ohne definierten Namen. Beispielsweise kann der folgende Code (der Dateiname ist 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() hier niemals als Parameter von B verwendet werden, da A kein „ anonyme" Funktion .

Also sollte es wie folgt geändert werden:

<?php$f = function () {return 100;
};function B(Closure $callback)
{return $callback();
}$a = B($f);print_r($a);//输出100
<?$func = function( $param ) {echo $param;
};$func( &#39;hello word&#39; );//输出:hello word

Abschluss implementieren

Anonyme Funktion einfügen gewöhnlich Es wird als Parameter in der Funktion übergeben und kann auch zurückgegeben werden. Dies implementiert einen einfachen Verschluss.

Im Folgenden gebe ich Ihnen drei Beispiele:

<?php//例一
//在函数里定义一个匿名函数,并且调用它function printStr() {$func = function( $str ) {echo $str;
    };$func( &#39; hello my girlfriend ! &#39; );
}
printStr();//输出 hello my girlfriend !

//例二
//在函数中把匿名函数返回,并且调用它function getPrintStrFunc() {$func = function( $str ) {echo $str;
    };return $func;
}$printStrFunc = getPrintStrFunc();$printStrFunc( &#39; do you  love me ? &#39; );//输出 do you  love me ?

//例三
//把匿名函数当做参数传递,并且调用它function callFunc( $func ) {$func( &#39; no!i hate you &#39; );
}$printStrFunc = function( $str ) {echo $str.&#39;<br>';
};
callFunc( $printStrFunc );//也可以直接将匿名函数进行传递。如果你了解js,这种写法可能会很熟悉callFunc( function( $str ) {echo $str; //输出no!i hate you
} );

Schlüsselwörter, die Abschlüsse und externe Variablen verbinden: VERWENDEN

Abschlüsse können den Standort speichern Einige Variablen und Werte des Codeblockkontexts. Standardmäßig können anonyme Funktionen in PHP keine Kontextvariablen in dem Codeblock aufrufen, in dem sie sich befinden, sondern müssen das Schlüsselwort use verwenden.

Schauen wir uns ein anderes Beispiel an (ok, ich habe wenig Geld, ich bin vulgär):

<?phpfunction getMoney() {$rmb = 1;$dollar = 8;$func = function() use ( $rmb ) {echo $rmb;echo $dollar;
    };$func();
}
getMoney();//输出:1

Wie Sie sehen können, ist der Dollar nicht In der Anweisung zum Verwenden des Schlüsselworts kann es in dieser anonymen Funktion nicht abgerufen werden. Achten Sie daher während der Entwicklung auf dieses Problem.

Einige Leute fragen sich vielleicht, ob Kontextvariablen in anonymen Funktionen geändert werden können, aber ich habe festgestellt, dass dies nicht möglich zu sein scheint:

<?phpfunction getMoney() {$rmb = 1;$func = function() use ( $rmb ) {echo $rmb.&#39;<br>';//把$rmb的值加1$rmb++;
    };$func();echo $rmb;
}

getMoney();//输出:
//1
//1

Nun, es stellt sich als nützlich heraus Was referenziert wird, ist lediglich ein Klon der Variablen. Aber was ist, wenn ich die Variable vollständig in Anführungszeichen setzen möchte, anstatt sie zu kopieren? Um diesen Effekt zu erzielen, fügen Sie einfach ein &-Symbol vor der Variablen hinzu:

<?phpfunction getMoney() {$rmb = 1;$func = function() use ( &$rmb ) {echo $rmb.&#39;<br>';//把$rmb的值加1$rmb++;
    };$func();echo $rmb;
}

getMoney();//输出:
//1
//2

Okay, also anonym Die Funktion kann dann auf die Kontextvariablen verweisen. Wenn die anonyme Funktion an die Außenwelt zurückgegeben wird, speichert die anonyme Funktion die durch die Verwendung referenzierten Variablen, die Außenwelt kann diese Variablen jedoch nicht abrufen. Auf diese Weise ist das Konzept des „Schließens“ möglicherweise klarer.

Ändern wir gemäß der Beschreibung das obige Beispiel:

<?phpfunction getMoneyFunc() {$rmb = 1;$func = function() use ( &$rmb ) {echo $rmb.&#39;<br>';//把$rmb的值加1$rmb++;
    };return $func;
}$getMoney = getMoneyFunc();$getMoney();$getMoney();$getMoney();//输出:
//1
//2
//3

Okay, so viel, wenn wir dann eine anonyme Funktion in einer Woolen-Klasse aufrufen möchten Tuch? Gehen Sie direkt zur Demo

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

wobei A::testA() eine unbenannte Funktion zurückgibt.

Das Konzept der Bindung

Der Abschluss im obigen Beispiel ist nur eine globale anonyme Funktion. Nun möchten wir eine Klasse angeben, die eine anonyme Funktion haben soll. Es kann auch verstanden werden, dass der Zugriffsbereich dieser anonymen Funktion nicht mehr global ist, sondern der Zugriffsbereich einer Klasse.

Dann müssen wir „eine anonyme Funktion an eine Klasse“ binden.

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

Im obigen Beispiel fDiesPersonanonymNameBuchstabeNummerMoNameseltsamwunderbarvonNach dem Binden ist es so, als gäbe es eine solche Funktion in A, aber unabhängig davon, ob diese Funktion öffentlich oder privat ist, gibt der letzte Parameter von bind diese Funktion an abrufbarer Bereich. Sie haben bindTo oben gesehen. Werfen wir einen Blick auf die Einführung auf der offiziellen Website Rückgabewert: Gibt ein neues Verschlussobjekt zurück oder Rückkehr bei Misserfolg

Schauen wir uns ein Beispiel an, um unser Verständnis zu vertiefen:

Lass uns Schauen Sie sich eine Demo an:
(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', 表示不改变。)


FALSEAnhand der obigen Beispiele ist es eigentlich nicht schwer, die anonyme Bindung zu verstehen.... Wir sehen uns eine erweiterte Demo an (Einführung von Merkmalsfunktionen).

<?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
Zum Beispiel nutzen wir jetzt die aktuelle Einkaufsumgebung

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

Zusätzlicher Hinweis: Abschlüsse können die USE-Taste verwenden, um externe Variablen zu verbinden.
Zusammenfassung: Die Eigenschaften von PHP-Verschlüssen können mit CLASS tatsächlich ähnliche oder sogar leistungsfähigere Funktionen erreichen, ganz zu schweigen von den Verschlüssen von js. Wir können uns nur auf Verbesserungen bei der Schließungsunterstützung von PHP in der Zukunft freuen. Allerdings sind anonyme Funktionen immer noch sehr nützlich, wenn Sie beispielsweise Funktionen wie preg_replace_callback verwenden, müssen Sie keine Callback-Funktion extern deklarieren. Durch die richtige Verwendung von Abschlüssen kann der Code prägnanter und verfeinert werden.

Das obige ist der detaillierte Inhalt vonEinführung in den Abschluss in PHP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn