PHPにおける匿名関数の深い理解


匿名関数の役割は関数の使用機能を拡大することであり、PHP 5.3以前にCallbackを渡す方法は、◆文字列の関数名◆create_を使用する2つの選択肢しかありません.functionの戻りはPHP 5である.3以降、Closureという選択肢が増えました.

      
      
      
      
  1. $func = function () { ... };   
  2. array_walk($arr$func);  
実装上、第1の方法は、関数名文字列の伝達が最も簡単である.2つ目の方法はfunction、実は第1の方法と本質的に同じで、create_functionは文字列の関数名を返します.この関数名のフォーマットは:

      
      
      
      
  1. "\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_func;  7. 新しい関数を返します.

      
      
      
      
  1. <?php  
  2. create_function(""'echo __FUNCTION__;');  
  3. call_user_func("\000lambda_1", 1);  
  4. ?>  
  5. //   __lambda_fun  
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クラスであるため、ベースクラスとしても子を産むことはできない.

      
      
      
      
  1. //php-5.3.0  
  2. $class = new ReflectionClass("Closure");  
  3. var_dump($class->isInternal());  
  4. var_dump($class->isAbstract() );  
  5. var_dump($class->isFinal());  
  6. var_dump($class->isInterface());  
  7. // :  
  8. bool(true)  
  9. bool(false)  
  10. bool(true)  
  11. bool(false)  
  12. ?>  
、PHP 5.3における閉パケットのサポートも、保持する外部変数のみをClosureオブジェクトとする「Static属性」(一般的な意味での遍歴/アクセス可能な属性ではない).

      
      
      
      
  1. //php-5.3.0  
  2. $b = "laruence";  
  3. $func = function($ause($b) {};  
  4. var_dump($func);  
  5. /*  :  
  6. object(Closure)#1 (2) {  
  7. ["static"]=>  
  8.  array(1) {  
  9. ["b"]=> string(8) "laruence"   
  10. }    
  11. ["parameter"]=>   
  12. array(1) {   
  13.  ["$a"]=> string(10) "<required>"   
  14.  }   
  15.  }   
  16.  */  
という実現は、個人的にはJSの閉パッケージへの支持に比べて、あまりにも粗末だと思います.(zehoa)