PHPの匿名関数を深く理解する

2191 ワード

PHPでは、Callbackを伝える方法が、ずっと醜い.PHP 5.3以前は2つの選択肢しかありませんでした.
1.        2.   create_function    

PHP 5.3以降、選択肢が一つ増えました.つまりClosureです.
$func = function () { ... };array_walk($arr, $func);

実装上、第1の方法は、関数の名前文字列を伝達することが最も簡単である.
2つ目の方法はfunction、実は第1の方法と本質的に同じで、create_functionは、文字列の関数名を返します.この関数名のフォーマットは次のとおりです.
"\000_lambda_" . count(anonymous_functions)++;

createを見てみましょうfunctionの実装手順:
1.     ,    2.     "function __lambda_func (  ) {    ;} "    3. eval 4.   __lambda_func       eval       ,       5.        :"\000_lambda_" . count(anonymous_functions)++6.         __lambda_func7.        

次のことを確認します.
<?phpcreate_function("", 'echo __FUNCTION__;');call_user_func("\000lambda_1", 1);?>//  __lambda_func

evalのとき、関数名は「」だったのでlambda_func」ということで匿名関数内に__が出力されますlambda_func、最後に使うので\000_lambda_” . count(anonymous_functions)++関数テーブルの名前を変更しました"_lambda_func」関数なので、"000_を通過できます.lambda_” . count(anonymous_functions)++はこの匿名関数を呼び出す.
これを確認するためにcreate_functionの戻り値dumpが表示されます.
PHP 5では3がリリースされたとき、new featureの1つは閉パッケージ/Lambda Functionをサポートしていました.私の最初の反応はzvalがISを追加したと思っていました.FUNCTIONですが、実際にはPHP 5が構築されています.3導入Closure"クラス"の例では、Closureクラスのコンストラクション関数はプライベートであるため、直接インスタンス化することはできず、またClosureクラスはFinalクラスであるため、ベースクラスの派生子クラスとしてもできない.
//php-5.3.0$class = new ReflectionClass("Closure");var_dump($class->isInternal());var_dump($class->isAbstract() );var_dump($class->isFinal());var_dump($class->isInterface());//  :bool(true)bool(false)bool(true)bool(false)?>

PHP 5.3における閉パケットのサポートは、保持する外部変数のみをClosureオブジェクトの"Static属性"(一般的な意味での遍歴/アクセス可能な属性ではない).
//php-5.3.0$b = "laruence";$func = function($a) use($b) {};var_dump($func);/*   :object(Closure)#1 (2) {  ["static"]=>  array(1) {    ["b"]=>    string(8) "laruence"  }  ["parameter"]=>  array(1) {    ["$a"]=>    string(10) "<required>"  }}*/

この実現は、個人的にはJSの閉パッケージへの支持に比べて、やはり少し粗末すぎると思います~