匿名函數小編使用得非常的少了在開發時一般用不到php匿名函數了,但在js中匿名函數用到比較多了,下文我來為各位介紹php中匿名函數用法.
PHP5.3起就支持匿名函數,可以放心在生產環境中使用,對于PHP的很多新特性該用的地方要大膽使用,可以使代碼更簡潔,功能實現也更加方便.
以下是PHP匿名函數的一個小的簡單實例:
- function func($list,$u_wangwang)
- {
- //匿名函數,獲取其他行聯號
- $other_num = function($num){
- $num = explode('.', $num);
- return $num[0];
- };
- $res = $other_num($v['sb_other_num']);
- return $res;
- }
首先在方法里定義了一個匿名函數,有一個參數,然后調用的時候進行傳參.
PHP中,傳遞Callback的方式,一直很丑陋,在PHP5.3以前,我們只有倆種選擇:
2.使用create_function的返回值
$func = function () { ... };
array_walk($arr, $func);
從實現上來說,第一種方式: 傳遞函數名字符串是最簡單的.
"/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.返回新的函數名
我們來驗證下:
- <?php
- create_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出來查看.
而在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) "<required>"
- }
- }
- */
這個實現,個人認為和JS對閉包的支持比起來,還是有些太簡陋了~
新聞熱點
疑難解答