深入理解PHP中的匿名函數

來源:互聯網
上載者:User

 

匿名函數的作用就是擴大函數的使用功能,在PHP 5.3以前,傳遞Callback的方式,我們只有倆種選擇:

◆字串的函數名

◆使用create_function的返回

在PHP5.3以後, 我們多了一個選擇, 也就是Closure。


  1. $func = function () { ... };  
  2. array_walk($arr, $func); 

從實現上來說, 第一種方式: 傳遞函數名字串是最簡單的。而第二種方式create_function, 其實和第一種方式本質上一樣的, create_function返回一個字串的函數名, 這個函數名的格式是:


  1. "\000_lambda_" . count(anonymous_functions)++ 
  2.  

我們來看看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. //輸出  
  6. __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就是支援閉包/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($a) use($b) {};  
  4. var_dump($func);  
  5. /* 輸出:  
  6. object(Closure)#1 (2) {  
  7. ["static"]=> 
  8. array(1) {  
  9. ["b"]=> 
  10. string(8) "laruence"  
  11. }  
  12. ["parameter"]=> 
  13. array(1) {  
  14. ["$a"]=> 
  15. string(10) "<required>"  
  16. }  
  17. }  
  18. */ 

這個實現, 個人認為和JS對閉包的支援比起來, 還是有些太簡陋了。



相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.