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 管理系统程序中的后门
Aug 05 PHP
支持中文的php加密解密类代码
Nov 27 PHP
PHP中使用GD库创建圆形饼图的例子
Nov 19 PHP
PHP中CheckBox多选框上传失败的代码写法
Feb 13 PHP
php array_reverse 以相反的顺序返回数组实例代码
Apr 11 PHP
PHP创建单例后台进程的方法示例
May 23 PHP
yii插入数据库防并发的简单代码
May 27 PHP
PHP观察者模式原理与简单实现方法示例
Aug 25 PHP
PHP基于imagick扩展实现合成图片的两种方法【附imagick扩展下载】
Nov 14 PHP
PHP从尾到头打印链表实例讲解
Sep 27 PHP
PHP扩展Swoole实现实时异步任务队列示例
Apr 13 PHP
ThinkPHP5&amp;5.1实现验证码的生成、使用及点击刷新功能示例
Feb 07 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
PHP脚本的10个技巧(2)
2006/10/09 PHP
PHP error_log()将错误信息写入一个文件(定义和用法)
2013/10/25 PHP
PHP根据传入参数合并多个JS和CSS文件的简单实现
2014/06/13 PHP
php从完整文件路径中分离文件目录和文件名的方法
2015/03/13 PHP
Ajax,UTF-8还是GB2312 eval 还是execScript
2008/11/13 Javascript
JavaScript this调用规则说明
2010/03/08 Javascript
jquery form表单序列化为对象的示例代码
2014/03/05 Javascript
jQuery使用之处理页面元素用法实例
2015/01/19 Javascript
js中for in语句的用法讲解
2015/04/24 Javascript
常用DOM整理
2015/06/16 Javascript
jquery动感漂浮导航菜单代码分享
2020/04/15 Javascript
jQuery实现漂亮实用的商品图片tips提示框效果(无图片箭头+阴影)
2016/04/16 Javascript
论Bootstrap3和Foundation5网格系统的异同
2016/05/16 Javascript
JavaScript中输出信息的方法(信息确认框-提示输入框-文档流输出)
2016/06/12 Javascript
Bootstrap的modal拖动效果
2016/12/25 Javascript
jQuery 循环遍历改变a标签的href(实例讲解)
2017/07/12 jQuery
jQuery获取复选框选中的当前行的某个字段的值
2017/09/15 jQuery
JavaScript canvas绘制圆弧与圆形
2020/02/18 Javascript
Python变量和数据类型详解
2017/02/15 Python
Python 简单计算要求形状面积的实例
2020/01/18 Python
解决安装新版PyQt5、PyQT5-tool后打不开并Designer.exe提示no Qt platform plugin的问题
2020/04/24 Python
HTML5注册页面示例代码
2014/03/27 HTML / CSS
全天然狗零食:Best Bully Sticks
2016/09/22 全球购物
加拿大消费电子和手机购物网站:The Source
2017/01/28 全球购物
英国家庭和商业健身器材购物网站:Fitness Options
2018/07/05 全球购物
《乡愁》教学反思
2014/02/18 职场文书
《孔子游春》教学反思
2014/02/25 职场文书
小摄影师教学反思
2014/04/27 职场文书
化学专业大学生职业生涯规划范文
2014/09/13 职场文书
财务助理岗位职责范本
2014/10/09 职场文书
营业用房租赁协议书
2014/11/26 职场文书
煤矿施工安全协议书
2016/03/22 职场文书
提升Nginx性能的一些建议
2021/03/31 Servers
详解Django的MVT设计模式
2021/04/29 Python
Java实现多文件上传功能
2021/06/30 Java/Android
webpack的移动端适配方案小结
2021/07/25 Javascript