時(shí)間:2015-06-28 00:00:00 來(lái)源:IT貓撲網(wǎng) 作者:網(wǎng)管聯(lián)盟 我要評(píng)論(0)
匿名函數(shù)的作用就是擴(kuò)大函數(shù)的使用功能,在PHP 5.3以前,傳遞Callback的方式,我們只有倆種選擇:
◆字符串的函數(shù)名
◆使用create_function的返回
51CTO推薦專題:PHP開(kāi)發(fā)基礎(chǔ)入門(mén)
在PHP5.3以后, 我們多了一個(gè)選擇, 也就是Closure。
- $func?=?function?()?{?...?}; ?
- array_walk($arr,?$func);?
從實(shí)現(xiàn)上來(lái)說(shuō), 第一種方式: 傳遞函數(shù)名字符串是最簡(jiǎn)單的。而第二種方式create_function, 其實(shí)和第一種方式本質(zhì)上一樣的, create_function返回一個(gè)字符串的函數(shù)名, 這個(gè)函數(shù)名的格式是:
- "\000_lambda_"?.?count(anonymous_functions)++?
- ?
我們來(lái)看看create_function的實(shí)現(xiàn)步驟:
1. 獲取參數(shù), 函數(shù)體;
2. 拼湊一個(gè)"function __lambda_func (參數(shù)) { 函數(shù)體;} "的字符串;
3. eval;
4. 通過(guò)__lambda_func在函數(shù)表中找到eval后得到的函數(shù)體, 找不到就出錯(cuò);
5. 定義一個(gè)函數(shù)名:"\000_lambda_" . count(anonymous_functions)++;
6. 用新的函數(shù)名替換__lambda_func;
7. 返回新的函數(shù)。
我們來(lái)驗(yàn)證下:
- php?
- create_function("",?'echo?__FUNCTION__;'); ?
- call_user_func("\000lambda_1",?1); ?
- ?>?
- //輸出 ?
- __lambda_fun?
因?yàn)樵趀val的時(shí)候, 函數(shù)名是"__lambda_func", 所以匿名函數(shù)內(nèi)會(huì)輸出__lambda_func, 而因?yàn)樽詈笥?\000_lambda_".count(anonymous_functions)++重命名了函數(shù)表中的"__lambda_func"函數(shù), 所以可通過(guò)"\000_lambda_" . count(anonymous_functions)++調(diào)用這個(gè)匿名函數(shù)。為了證實(shí)這一點(diǎn), 可以將create_function的返回值dump出來(lái)查看。
而在PHP 5.3發(fā)布的時(shí)候, 其中有一條new feature就是支持閉包/Lambda Function, 我第一反應(yīng)是以為zval新增了一個(gè)IS_FUNCTION, 但實(shí)際上是構(gòu)造了一個(gè)PHP 5.3引入的Closure"類"的實(shí)例, Closure類的構(gòu)造函數(shù)是私有的, 所以不能被直接實(shí)例化, 另外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中對(duì)閉包的支持, 也僅僅是把要保持的外部變量, 做為Closure對(duì)象的"Static屬性"(并不是普通意義上的可遍歷/訪問(wèn)的屬性).
- //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>" ?
- } ?
- } ?
- */?
這個(gè)實(shí)現(xiàn), 個(gè)人認(rèn)為和JS對(duì)閉包的支持比起來(lái), 還是有些太簡(jiǎn)陋了。
關(guān)鍵詞標(biāo)簽:PHP,匿名函數(shù)
相關(guān)閱讀
熱門(mén)文章
plsql developer怎么連接數(shù)據(jù)庫(kù)-plsql developer連接數(shù)據(jù)庫(kù)方法
2021年最好用的10款php開(kāi)發(fā)工具推薦
php利用淘寶IP庫(kù)獲取用戶ip地理位置
在 PHP 中使用命令行工具
人氣排行 詳解ucenter原理及第三方應(yīng)用程序整合思路、方法 plsql developer怎么連接數(shù)據(jù)庫(kù)-plsql developer連接數(shù)據(jù)庫(kù)方法 PHP中防止SQL注入攻擊 PHP會(huì)話Session的具體使用方法解析 PHP運(yùn)行出現(xiàn)Notice : Use of undefined constant 的解決辦法 PHP如何清空mySQL數(shù)據(jù)庫(kù) CakePHP程序員必須知道的21條技巧 PHP采集圖片實(shí)例(PHP采集)