php 函數的嵌套


  1. /*一定要小心變量作用域*/
  2. function insert_dynamic()  
  3. {  
  4.   function bar()  
  5.   {  
  6.     echo "I don't exist until insert_dynamic() is called.\n";  
  7.   }  
  8. }
  9.   
  10. /* 現在還不能調用bar()函數,因為它還不存在 */  
  11.   
  12. insert_dynamic();
  13.   
  14. /* 現在可以調用bar()函數了,因為insert_dynamic()函數 
  15.    的執行使得bar()函數變為已定義的函數 */  
  16.   
  17. bar(); 
全局和局部要搞清。

擴展

PHP中的函數嵌套層數限制分析

 

函數嵌套,這個名字有點糾結,也許不太好理解。一個比較常見的函數嵌套特例:遞歸函數,即函數自己嵌套自己。 一直以為在PHP中不能有太多的函數嵌套,這是因為在以前某些時候不小心用到了遞歸,在遞歸的深度達到100時, 即函數嵌套的層數達到100時,程序會報一個 Fatal error。如下示例: 

復制代碼代碼如下:

 


function rt() { 
static $i; 
echo $i++, '<br />'; 
rt(); 

rt(); 
die(); 

在我的win7 + php5.3的環境下報錯如下: Fatal error:Maximum function nesting level of ‘100′ reached, aborting! 

一直以為是PHP本身的限制,直到某一天切換到liunx環境下以命令行的模式運行,發現,程序限入了死循環。 不同的環境下有不同的結果,為什么呢?好吧,我們直接在源碼中查找報錯信息,發現沒有相關內容,直接debug整個執行過程,也沒有在win下的報錯。 什么原因?再次切換到win下,再次查找,發現在xdebug中看到了報錯信息。在xdebug.c文件的1242行開始: 
復制代碼代碼如下:

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)); 

這表示什么?之前的函數嵌套的層數限制是xdebug擴展加上的,為什么會有這個限制了呢?在xdebug中,xdebug中會記錄每次函數調用, 包括嵌套的函數調用,函數調用中的內存,時間等值,這些值在分析程序性能時有大用。如果沒有這個限制,當嵌套的層數太多,機器會內存耗盡。 如果這是一台生產環境的服務器,那么就會有部分服務不可用,當然生產環境下是不會添加這個擴展的。但是在多人共用的開發服務器上就可能有這個擴展, 如果因為一個開發人員的程序錯誤導致機器不可用,從而使所有的開發人員不能工作,我想這也許是添加限制的原因吧。 

如果我們需要把這個限制的層數加大,怎么辦呢?改源碼,重新編譯xdebug擴展?不需要,在xdebug的配置項中有一項叫做xdebug.max_nesting_level, 默認情況下,在php.ini中這個配置項是被注釋了的,去掉注釋,將這個值成你所需要的值,200?不夠,那500吧,但是這個值還是不要太大, 如果遞歸太多,對程序的性能有很大的影響,此時,以棧的形式實現遞歸或者用循環替換遞歸會是一個更好的方案, 如:斐波那契數列(Fibonacci)的實現,用循環來實現會更快。 

結論:PHP本身的函數嵌套是沒有限制的,如果說有限制,也是內存的限制。這是因為PHP的函數嵌套是以棧的形式實現的。對於每個函數都會分配一段內存來存儲函數局部的內容。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM