PHP中的函数嵌套层数限制分析


Posted in PHP onJune 13, 2011

函数嵌套,这个名字有点纠结,也许不太好理解。一个比较常见的函数嵌套特例:递归函数,即函数自己嵌套自己。 一直以为在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的函数嵌套是以栈的形式实现的。对于每个函数都会分配一段内存来存储函数局部的内容。

PHP 相关文章推荐
php5数字型字符串加解密代码
Apr 24 PHP
smarty模板嵌套之include与fetch性能测试
Dec 05 PHP
PHP中如何判断AJAX提交的数据
Feb 05 PHP
php ci框架验证码实例分析
Jun 26 PHP
php生成图形验证码几种方法小结
Aug 15 PHP
php实现cc攻击防御和防止快速刷新页面示例
Feb 13 PHP
php更新修改excel中的内容实例代码
Feb 26 PHP
php实现文件编码批量转换
Mar 10 PHP
ecshop实现smtp发送邮件
Feb 03 PHP
详谈php静态方法及普通方法的区别
Oct 04 PHP
PHP实现ASCII码与字符串相互转换的方法
Apr 29 PHP
php生成二维码不保存服务器还有下载功能的实现代码
Aug 09 PHP
PHP5中新增stdClass 内部保留类
Jun 13 #PHP
php中使用Akismet防止垃圾评论的代码
Jun 10 #PHP
php中通过虚代理实现延迟加载的实现代码
Jun 10 #PHP
php获取后台Job管理的实现代码
Jun 10 #PHP
php下通过curl抓取yahoo boss 搜索结果的实现代码
Jun 10 #PHP
PHP缩略图等比例无损压缩,可填充空白区域补充色
Jun 10 #PHP
PHP网站备份程序代码分享
Jun 10 #PHP
You might like
yii2中LinkPager增加总页数和总记录数的实例
2017/08/28 PHP
HTML5附件拖拽上传drop &amp; google.gears实现代码
2011/04/28 Javascript
jquery ajax 同步异步的执行 return值不能取得的解决方案
2012/01/08 Javascript
js获取多个tagname的节点数组
2013/09/22 Javascript
jQuery控制iFrame(实例代码)
2013/11/19 Javascript
javascript查询字符串参数的方法
2015/01/28 Javascript
javascript内置对象操作详解
2015/02/04 Javascript
jQuery源码解读之removeAttr()方法分析
2015/02/20 Javascript
浅谈jQuery页面的滚动位置scrollTop、scrollLeft
2015/05/19 Javascript
Javascript实现商品秒杀倒计时(时间与服务器时间同步)
2015/09/16 Javascript
JS使用JSON作为参数实例分析
2016/06/23 Javascript
JS调用打印机功能简单示例
2016/11/28 Javascript
React中jquery引用的实现方法
2017/09/12 jQuery
node中modules.exports与exports导出的区别
2018/06/08 Javascript
Electron autoUpdater实现Windows安装包自动更新的方法
2018/12/24 Javascript
JS实现从对象获取对象中单个键值的方法示例
2019/06/05 Javascript
小程序调用微信支付的方法
2019/09/26 Javascript
[59:15]EG vs LGD 2018国际邀请赛淘汰赛BO3 第一场 8.26
2018/08/29 DOTA
Python爬虫使用脚本登录Github并查看信息
2018/07/16 Python
推荐10款最受Python开发者欢迎的Python IDE
2018/09/16 Python
浅谈python常用程序算法
2019/03/22 Python
python批量识别图片指定区域文字内容
2019/04/30 Python
pycharm配置git(图文教程)
2019/08/16 Python
python并发编程多进程 互斥锁原理解析
2019/08/20 Python
完美解决pycharm导入自己写的py文件爆红问题
2020/02/12 Python
520使用Python实现“我爱你”表白
2020/05/20 Python
python 制作磁力搜索工具
2021/03/04 Python
CSS3 实用技巧:实现黑白图像效果示例代码
2013/07/11 HTML / CSS
英国最大的在线快递公司之一:ParcelHero
2019/11/04 全球购物
写一个用矩形法求定积分的通用函数
2012/11/08 面试题
个人工作保证书
2015/02/28 职场文书
2015秋学期开学寄语
2015/05/28 职场文书
思品教学工作总结
2015/08/10 职场文书
2016保送生自荐信范文
2016/01/29 职场文书
初中教务主任竞聘演讲稿(范文)
2019/08/20 职场文书
导游词之张家口
2019/12/13 职场文书