クロージャは、作成時に周囲の状態をカプセル化する関数を指します。たとえクロージャが配置されている環境が存在しなくても、クロージャ内にカプセル化された状態はまだ存在します。
匿名関数は実際には名前のない関数であり、他の PHP 関数オブジェクトと同様に変数に代入して渡すことができます。ただし、匿名関数は依然として関数であるため、呼び出したりパラメーターを渡したりできるため、関数またはメソッドのコールバックとして適しています。
注: 理論的には、クロージャと匿名関数は異なる概念ですが、PHP ではこれらを同じ概念として扱います (匿名関数は PHP ではクロージャ関数とも呼ばれます)。そのため、以下でクロージャについて言及するときは、それらを指します。逆に。
<?php$greet = function ($name) { return sprintf("Hello %s\r\n", $name);};echo $greet('LaravelAcademy.org');
Hello LaravelAcademy.org
注: $greet 変数を呼び出すことができる理由は、この変数の値がクロージャであり、変数名の後に () がある限り、クロージャ オブジェクトが __invoke() マジック メソッドを実装しているためです。 PHP はそれを検索し、__invoke メソッドを呼び出します。
通常、PHP クロージャは関数やメソッドのコールバックとして使用されます。実際、array_map や preg_replace_callback などの多くの PHP 関数は、PHP 匿名関数を使用する絶好の機会です。クロージャは、他の値と同様に、パラメータとして他の PHP 関数に渡すことができることを覚えておいてください:
<?php$numberPlusOne = array_map(function ($number) { return $number += 1;}, [1, 2, 3]);print_r($numberPlusOne);
<?phpfunction incrementNumner ($number) { return $number += 1;}$numberPlusOne = array_map(‘incrementNumber’, [1, 2, 3]);print_r($numberPlusOne);
キーワードを使用する
実際、クロージャは Laravel フレームワークでも広く使用されています。最も一般的なものはルート定義です:
Route::group(['domain' => '{account}.myapp.com'], function () { Route::get('user/{id}', function ($account, $id) { // });});
このメソッドの機能は、トランザクションを使用してモデル データを保存することです。ここでは、クロージャを使用して保存された状態を返し、use キーワードを使用して親スコープの $options をクロージャに渡し、このデータにアクセスできるようにします。
さらに、Model クラスの ForceFill メソッドなど、複数の親スコープ変数をクロージャに渡すこともサポートしています。
複数の変数はカンマで区切ることができます。
bindTo メソッド
クロージャはオブジェクトであることを前に述べました。そのため、クロージャ内で $this キーワードを使用してクロージャ オブジェクトの内部状態を取得できます。Pay は役に立ちません。 __invoke magic メソッドと bindingTo メソッドに注意してください。__invoke の役割については前述しましたが、関数を呼び出してオブジェクトを呼び出そうとすると、__invoke() メソッドが自動的に呼び出されます。
次に、bindTo メソッドを見てみましょう。このメソッドを通じて、クロージャの内部状態を他のオブジェクトにバインドできます。ここでは、bindTo メソッドの 2 番目のパラメータが特に重要です。その機能は、バインドされたクロージャのオブジェクトが属する PHP クラスを指定することにより、クロージャは他の場所からバインドされたクロージャの保護されたオブジェクトとプライベート オブジェクトにアクセスできるようになります。 . メンバー変数。
PHP フレームワークは、ルーティング URL を匿名コールバック関数にマップするために、bindTo メソッドをよく使用することがわかります。フレームワークは、匿名コールバック関数をアプリケーション オブジェクトにバインドし、匿名関数で $this キーワードを使用できるようにします。重要な参照 アプリケーション オブジェクト:
<?phpclass App { protected $routes = []; protected $responseStatus = '200 OK'; protected $responseContentType = 'text/html'; protected $responseBody = 'Laravel学院'; public function addRoute($routePath, $routeCallback) { $this->routes[$routePath] = $routeCallback->bindTo($this, __CLASS__); } public function dispatch($currentPath) { foreach ($this->routes as $routePath => $callback) { if( $callback === $currentPath) { $callback(); } } header('HTTP/1.1 ' . $this->responseStatus); header('Content-Type: ' . $this->responseContentType); header('Content-Length: ' . mb_strlen($this->responseBody)); echo $this->responseBody; }}
$app = new App();$app->addRoute(‘user/nonfu’, function(){ $this->responseContentType = ‘application/json;charset=utf8’; $this->responseBody = ‘{“name”:”LaravelAcademy"}';});$app->dispatch(‘user/nonfu');