クロージャは、作成時に状態をカプセル化する関数を指します。匿名関数は、名前のない関数を指します。 PHP では、クロージャと匿名関数は同じものとして扱われます。理論は異なりますが、クロージャは匿名関数で構成される「構造」であると理解できます。
string、int などと同様に、クロージャー関数は変数の値として使用できます。 PHP は、この式を組み込みクラス Closure のオブジェクト インスタンスに自動的に変換します。クロージャオブジェクトを変数に代入する方法は通常の変数代入の構文と同じで、最後にセミコロンも追加されます。
うーん
クロージャの状況は次のとおりです:
1. Closure クラスを継承するクロージャ オブジェクトを作成します
2. Closure クラスに __invoke() メソッドを実装します
2.クロージャーは $anonyFunc オブジェクト
3 に割り当てられます。呼び出し変数名の後に () があり、__invoke() メソッドが実際に呼び出されます
array_map の例では、このアプローチは従来の方法よりも簡単です。最初に関数を定義してから呼び出しを行う方法では、コールバックの実装が使用場所から分離されます。
$anonyFunc = function ($name) { return 'Hello ' . $name;}; echo $anonyFunc->__invoke("Josh");echo $anonyFunc("Josh");
useparameters
<?php$numbersPlusOne = array_map(function ($number) { return $number +1;}, [1,2,3]);print_r($numbersPlusOne);// 输出 --> [2,3,4]
bindTo()
Closure には、bindTo() というメソッドがあり、Closure オブジェクトの内部状態を他のオブジェクトにバインドできます。最初のパラメータが特定の新しいクラス変数である場合、特定のクラスの protected および private を読み取りたい場合は、bindTo の 2 番目のパラメータにクラス名を文字列形式で書き込む必要があります。これを新しいクラス変数として指定すると、PHP はそれを文字列のクラス名に変換するため、クラス内に文字列クラス名を直接記述することをお勧めします。これを実行した後、匿名関数で $this キーワードを使用して、重要なアプリケーション オブジェクトを参照できます。
<?phpfunction enclosePerson($name) { return function ($doCommand) use ($name) { return sprintf('%s, %s', $name, $doCommand); };}// 将字符串"Clay"封装进闭包$clay = enclosePerson('Clay'); // 调用闭包echo $clay('get me sweet tea!');// 输出 --> "Clay, get me sweet tea!"
bindTo() メソッドは、ルーティング アドレスを匿名コールバック関数にマップするために一部の PHP フレームワークでよく使用されます。これらのフレームワークは、匿名関数をアプリケーション オブジェクトにバインドします。匿名関数で $this キーワードを使用すると、アプリケーション オブジェクトを参照できます
class Foo{ private $name; function __construct($name){ $this->name = $name; }}$obj = new Foo('Sam');$cl = function() { return "Hello " . $this->name;};$cl = $cl->bindTo($obj, 'Foo');// 'Foo'也可以直接写成$objecho($cl());
Call
<?phpclass App{ protected $routes = array(); protected $responseStatus = '200 OK'; protected $responseContentType = 'text/html'; protected $responseBody = 'Hello world'; public function addRoute($routePath, $routeCallback) { $this->routes[$routePath] = $routeCallback->bindTo($this, __CLASS__); } public function dispatch($currentPath) { foreach ($this->routesas $routePath => $callback) { if ($routePath === $currentPath) { $callback(); } } header('HTTP/1.1 ' . $this->responseStatus); header('Content-type: ' . $this->responseContentType); header('Content-length: ' . mb_strlen($this->responseBody)); echo $this->responseBody; }}
参考:
http://oomusou.io/php/php-bindTo/
《modern php 》