クロージャ クラス
匿名関数を表すために使用されるクラス。
匿名関数 (PHP 5.3 で導入) は、このタイプのオブジェクトを生成します。以前は、このクラスは実装の詳細とみなされていましたが、現在はこのクラスに依存して何かを行うことができます。 PHP 5.4 以降、このクラスには、作成後の匿名関数をより詳細に制御できるメソッドが付属しています。
このクラスはインスタンス化できません。このクラスには 2 つの主要なメソッドがあり、どちらもクロージャをコピーするために使用されます。1 つは静的メソッド、もう 1 つは動的メソッドです。これらの 2 つの理解しにくいメソッドについて詳しく説明します。下に。
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.
パラメータの説明:
クロージャは匿名でバインドする必要があります関数。
newこれには、匿名関数にバインドされたオブジェクト、または非バインド クロージャを作成するには NULL が必要です。
newscope はクロージャのクラス スコープにバインドされる必要があります。または、「静的」は変更がないことを意味します。オブジェクトが渡された場合は、オブジェクトの型名が使用されます。クラス スコープは、クロージャ内の $this オブジェクトのプライベートな保護されたメソッドの可視性を決定するために使用されます。
クロージャを関連付けるクラス スコープ、または
現在のものを保持する 'static' オブジェクトが指定された場合、代わりにオブジェクトのタイプが使用されます。これにより、バインドされたオブジェクトの
protected メソッドとプライベート メソッドの可視性が決定されます。
上記はメソッドの定義です。
最初のパラメータはクロージャ関数なので分かりやすいですが、
2 番目のパラメータは分かりにくいです。コピーするクロージャに $this
が含まれている場合、thisオブジェクトは、この $this
を表します。クロージャ関数でのこのオブジェクトへの変更は、属性の変更など、呼び出し完了後も一貫性が保たれます。
3 番目のパラメータはそれほど簡単ではありませんデフォルトのパラメータでは、object $newthis
の属性関数にアクセスするために $this->
を呼び出すと、制限があります。 public
属性を持つ関数にのみアクセスできます。protected/private
属性にアクセスしたい場合は、クラス内と同様に、対応するクラス名/クラス インスタンスに設定する必要があります。 、そのクラスの 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();
上記のコードはエラーを報告します致命的エラー: キャッチされないエラー: コンテキスト 'Closure から保護されたメソッド T::who() を呼び出します###。 bind の 3 番目のパラメータを
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 . このとき、3 番目のパラメータを追加します パラメータは 1 つだけで十分です。3 番目のパラメータが
$this のスコープに影響を与えるだけでなく、
がパラメータのスコープにも影響を与える可能性があることがわかります。
Closure::bindTo
bindTo には
bind と同様の関数があります。ここでは単にもう 1 つ どちらの形式でも
現在のクロージャ オブジェクトをコピーし、指定された $this オブジェクトとクラス スコープをバインドします。 、最初のパラメータは
bind より小さい、
最後の 2 つは同じです。もちろん、
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
a と似ています。トリック
この関数は、composer によって生成された自動読み込みソース コードを調べているときに見つかりました。これは、composer で特別な方法で使用されます。以下は、次のコードの一部のインターセプトです。 combos// 文件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 が使用されています。これはクロージャと外部変数を接続するブリッジです。
なぜここで通常のパラメータを渡すことができるかというと、php5ではオブジェクトの仮パラメータと実パラメータが同じオブジェクトを指しており、関数内でオブジェクトを変更するとオブジェクトの外にも反映されるからです。
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); }
概要
私はまだやっていません。ブログを長く続けていると、イライラして落ち着かないこともあれば、書きたいことが見つからないこともあります。それでも落ち着いて、すべてをうまくやり、物事が起こっても動揺せず、広い心を保ち、すべてを冷静に処理する必要があります。関連チュートリアルの推奨事項: 「PHP チュートリアル 」
以上がClosure を使用して PHP で匿名関数を作成する方法の概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。