深入理解PHP之匿名函數

發表于:2013-10-17來源:IT博客大學習作者:雪候鳥點擊數: 標簽:php
PHP中, 傳遞Callback的方式, 一直很丑陋. 在PHP5.3以前, 我們只有倆種選擇: 1. 字符串的函數名2. 使用create_function的返回 在PHP5.3以后, 我們多了一個選擇, 也就是Closure,

  PHP中, 傳遞Callback的方式, 一直很丑陋. 在PHP5.3以前, 我們只有倆種選擇:

  1. 字符串的函數名2. 使用create_function的返回

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

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

  從實現上來說, 第一種方式: 傳遞函數名字符串是最簡單的.

  而第二種方式create_function, 其實和第一種方式本質上一樣的, 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. 返回新的函數

  我們來驗證下:

  //輸出__lambda_fun

  因為在eval的時候, 函數名是”__lambda_func”, 所以匿名函數內會輸出__lambda_func, 而因為最后用”\000_lambda_” . count(anonymous_functions)++重命名了函數表中的”__lambda_func”函數, 所以可通過”\000_lambda_” . count(anonymous_functions)++調用這個匿名函數.

  為了證實這一點, 可以將create_function的返回值dump出來查看.

  而在PHP5.3發布的時候, 其中有一條new feature就是支持閉包/Lambda Function, 我第一反應是以為zval新增了一個IS_FUNCTION, 但實際上是構造了一個PHP5.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)?>

  而PHP5.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) ""}}*/

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

原文轉自:http://blogread.cn/it/article/1848

国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97