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 相关文章推荐
PHP 导出数据到淘宝助手CSV的方法分享
Feb 27 PHP
最新用php获取谷歌PR值算法,附上php查询PR值代码示例
Dec 25 PHP
调试一段PHP程序时遇到的三个问题
Jan 17 PHP
PHP 在5.1.* 和5.2.*之间 PDO数据库操作中的不同之处小结
Mar 07 PHP
ajax取消挂起请求的处理方法
Mar 18 PHP
PHP正则表达式 /i, /is, /s, /isU等介绍
Oct 23 PHP
php实现按照权重随机排序数据的方法
Jan 09 PHP
PHP将进程作为守护进程的方法
Mar 19 PHP
Laravel 5框架学习之向视图传送数据(进阶篇)
Apr 08 PHP
php简单实现批量上传图片的方法
May 09 PHP
PHP 7安装使用体验之性能大提升,兼容性强,扩展支持不够(升级PHP要谨慎)
Jul 27 PHP
php设计模式之观察者模式定义与用法经典示例
Sep 19 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
重新封装zend_soap实现http连接安全认证的php代码
2011/01/12 PHP
php错误级别的设置方法
2013/06/17 PHP
yii2 commands模式以及配置crontab定时任务的方法
2017/08/19 PHP
PHP利用DWZ.CN服务生成短网址
2019/08/11 PHP
关于Yii中模型场景的一些简单介绍
2019/09/22 PHP
一个很简单的办法实现TD的加亮效果.
2006/06/29 Javascript
js 兼容多浏览器的回车和鼠标焦点事件代码(IE6/7/8,firefox,chrome)
2010/04/14 Javascript
JavaScript学习历程和心得小结
2010/08/16 Javascript
js控制淡入淡出示例代码
2013/11/12 Javascript
jQuery中get()方法用法实例
2014/12/27 Javascript
JavaScript中利用Array和Object实现Map的方法
2015/07/27 Javascript
chrome浏览器当表单自动填充时如何去除浏览器自动添加的默认样式
2015/10/09 Javascript
Angularjs整合微信UI(weui)
2016/03/15 Javascript
javascript运算符——位运算符全面介绍
2016/07/14 Javascript
AngularJS实现星星等级评分功能
2016/09/24 Javascript
AngularJS上传文件的示例代码
2018/11/10 Javascript
微信小程序仿知乎实现评论留言功能
2018/11/28 Javascript
微信小程序实现带参数的分享功能(两种方法)
2019/05/17 Javascript
全面解析Vue中的$nextTick
2020/12/24 Vue.js
python 实现上传图片并预览的3种方法(推荐)
2017/07/14 Python
树莓派+摄像头实现对移动物体的检测
2019/06/22 Python
使用python 对验证码图片进行降噪处理
2019/12/18 Python
基于Pycharm加载多个项目过程图解
2020/01/19 Python
python读取mysql数据绘制条形图
2020/03/25 Python
Python 多进程原理及实现
2020/12/21 Python
美国网上书店:Barnes & Noble
2018/08/15 全球购物
高中自我评价范文
2014/01/27 职场文书
《诚实与信任》教学反思
2014/04/10 职场文书
校园环保建议书
2014/05/14 职场文书
学生会感恩节活动方案
2014/10/11 职场文书
党委班子纠正“四风”问题整改措施
2014/10/28 职场文书
2014年驾驶员工作总结
2014/11/18 职场文书
大连导游词
2015/02/12 职场文书
2015年小学数学教师个人工作总结
2015/05/25 职场文书
幼儿园托班开学寄语(2016秋季)
2015/12/03 职场文书
《帝国时代4》赛季预告 新增内容编译器可创造地图
2022/04/03 其他游戏