PHP中的函數(shù)嵌套層數(shù)限制分析
function rt() {
static $i;
echo $i++, '<br />';
rt();
}
rt();
die();
在我的win7 + php5.3的環(huán)境下報(bào)錯(cuò)如下: Fatal error:Maximum function nesting level of ‘100′ reached, aborting!
一直以為是PHP本身的限制,直到某一天切換到liunx環(huán)境下以命令行的模式運(yùn)行,發(fā)現(xiàn),程序限入了死循環(huán)。 不同的環(huán)境下有不同的結(jié)果,為什么呢?好吧,我們直接在源碼中查找報(bào)錯(cuò)信息,發(fā)現(xiàn)沒(méi)有相關(guān)內(nèi)容,直接debug整個(gè)執(zhí)行過(guò)程,也沒(méi)有在win下的報(bào)錯(cuò)。 什么原因?再次切換到win下,再次查找,發(fā)現(xiàn)在xdebug中看到了報(bào)錯(cuò)信息。在xdebug.c文件的1242行開(kāi)始:
XG(level)++;
if (XG(level) == XG(max_nesting_level)) {
php_error(E_ERROR, "Maximum function nesting level of '%ld' reached,
aborting!", XG(max_nesting_level));
}
這表示什么?之前的函數(shù)嵌套的層數(shù)限制是xdebug擴(kuò)展加上的,為什么會(huì)有這個(gè)限制了呢?在xdebug中,xdebug中會(huì)記錄每次函數(shù)調(diào)用, 包括嵌套的函數(shù)調(diào)用,函數(shù)調(diào)用中的內(nèi)存,時(shí)間等值,這些值在分析程序性能時(shí)有大用。如果沒(méi)有這個(gè)限制,當(dāng)嵌套的層數(shù)太多,機(jī)器會(huì)內(nèi)存耗盡。 如果這是一臺(tái)生產(chǎn)環(huán)境的服務(wù)器,那么就會(huì)有部分服務(wù)不可用,當(dāng)然生產(chǎn)環(huán)境下是不會(huì)添加這個(gè)擴(kuò)展的。但是在多人共用的開(kāi)發(fā)服務(wù)器上就可能有這個(gè)擴(kuò)展, 如果因?yàn)橐粋€(gè)開(kāi)發(fā)人員的程序錯(cuò)誤導(dǎo)致機(jī)器不可用,從而使所有的開(kāi)發(fā)人員不能工作,我想這也許是添加限制的原因吧。
如果我們需要把這個(gè)限制的層數(shù)加大,怎么辦呢?改源碼,重新編譯xdebug擴(kuò)展?不需要,在xdebug的配置項(xiàng)中有一項(xiàng)叫做xdebug.max_nesting_level, 默認(rèn)情況下,在php.ini中這個(gè)配置項(xiàng)是被注釋了的,去掉注釋,將這個(gè)值成你所需要的值,200?不夠,那500吧,但是這個(gè)值還是不要太大, 如果遞歸太多,對(duì)程序的性能有很大的影響,此時(shí),以棧的形式實(shí)現(xiàn)遞歸或者用循環(huán)替換遞歸會(huì)是一個(gè)更好的方案, 如:斐波那契數(shù)列(Fibonacci)的實(shí)現(xiàn),用循環(huán)來(lái)實(shí)現(xiàn)會(huì)更快。
結(jié)論:PHP本身的函數(shù)嵌套是沒(méi)有限制的,如果說(shuō)有限制,也是內(nèi)存的限制。這是因?yàn)镻HP的函數(shù)嵌套是以棧的形式實(shí)現(xiàn)的。對(duì)于每個(gè)函數(shù)都會(huì)分配一段內(nèi)存來(lái)存儲(chǔ)函數(shù)局部的內(nèi)容。
相關(guān)文章
聊聊PHP中require_once()函數(shù)為什么不好用
php中你大概有發(fā)現(xiàn)require_once()不好用,但是沒(méi)有深究過(guò)它為什么不好用,這篇文章從該函數(shù)的定義和用法聊聊不好用的原因,文中講述的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考價(jià)值2021-09-09php實(shí)現(xiàn)的后臺(tái)表格分頁(yè)功能示例
這篇文章主要介紹了php實(shí)現(xiàn)的后臺(tái)表格分頁(yè)功能,涉及php針對(duì)數(shù)據(jù)庫(kù)的連接、查詢、刪除、動(dòng)態(tài)生成表格等相關(guān)操作技巧,需要的朋友可以參考下2017-10-10PHP中for循環(huán)與foreach的區(qū)別
本文主要介紹了php中for循環(huán)與foreach的區(qū)別,具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧2017-03-03關(guān)于PHP堆棧與列隊(duì)的學(xué)習(xí)
本篇文章是對(duì)PHP中的堆棧與列隊(duì)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06PHP中通過(guò)加號(hào)合并數(shù)組的一個(gè)簡(jiǎn)單方法分享
通常,我們合并多個(gè)數(shù)組用的是array_merge()函數(shù),其實(shí),PHP手冊(cè)中關(guān)于數(shù)組操作符的介紹給了我們更簡(jiǎn)單的方法,那就是"+"號(hào),看看下面的例子就明白了(詳細(xì)了解)2011-01-01PHP中的strtr函數(shù)使用介紹(str_replace)
PHP的 strtr 函數(shù), 性能要比 str_replace 函數(shù)高, 可以代替 str_replace 來(lái)使用2011-10-10PHP查詢大量數(shù)據(jù)內(nèi)存耗盡問(wèn)題的解決方法
這篇文章主要為大家詳細(xì)介紹了PHP查詢大量數(shù)據(jù)內(nèi)存耗盡問(wèn)題的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-10-10php number_format() 函數(shù)通過(guò)千位分組來(lái)格式化數(shù)字的實(shí)現(xiàn)代碼
以下是對(duì)php中的number format()函數(shù)通過(guò)千位分組來(lái)格式化數(shù)字的實(shí)現(xiàn)代碼進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過(guò)來(lái)參考下2013-08-08