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程序?
Dec 08 PHP
PHP生成Flash动画的实现代码
Mar 12 PHP
PHP MemCached高级缓存配置图文教程
Aug 05 PHP
PHP求小于1000的所有水仙花数的代码
Jan 10 PHP
php控制linux服务器常用功能 关机 重启 开新站点等
Sep 05 PHP
如何用C语言编写PHP扩展的详解
Jun 13 PHP
windows服务器中检测PHP SSL是否开启以及开启SSL的方法
Apr 25 PHP
Centos下升级php5.2到php5.4全记录(编译安装)
Apr 03 PHP
PHP防止刷新重复提交页面的示例代码
Nov 11 PHP
详解PHP中foreach的用法和实例
Oct 25 PHP
PHP环境搭建(php+Apache+mysql)
Nov 14 PHP
PHP实现基于栈的后缀表达式求值功能
Nov 10 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
腾讯QQ微博API接口获取微博内容
2013/10/30 PHP
javascript实现的listview效果
2007/04/28 Javascript
jQuery 无刷新分页实例代码
2013/11/12 Javascript
JavaScript正则表达式之multiline属性的应用
2015/06/16 Javascript
理解javascript中的原型和原型链
2015/07/30 Javascript
ionic 上拉菜单(ActionSheet)实例代码
2016/06/06 Javascript
基于JavaScript实现鼠标箭头移动图片跟着移动
2016/08/30 Javascript
微信小程序 实现拖拽事件监听实例详解
2016/11/16 Javascript
Bootstrap禁用响应式布局的实现方法
2017/03/09 Javascript
JavaScript之json_动力节点Java学院整理
2017/06/29 Javascript
微信公众平台 发送模板消息(Java接口开发)
2019/04/17 Javascript
原生JavaScript实现滑动拖动验证的示例代码
2019/12/06 Javascript
使用PYTHON接收多播数据的代码
2012/03/01 Python
python采用requests库模拟登录和抓取数据的简单示例
2014/07/05 Python
python使用BeautifulSoup分析网页信息的方法
2015/04/04 Python
Python中的ceil()方法使用教程
2015/05/14 Python
解决PyCharm中光标变粗的问题
2017/08/05 Python
用python实现k近邻算法的示例代码
2018/09/06 Python
Pycharm2017版本设置启动时默认自动打开项目的方法
2018/10/29 Python
TensorFlow基于MNIST数据集实现车牌识别(初步演示版)
2019/08/05 Python
windows 10 设定计划任务自动执行 python 脚本的方法
2019/09/11 Python
通过实例了解python property属性
2019/11/01 Python
Python中if有多个条件处理方法
2020/02/26 Python
python属于软件吗
2020/06/18 Python
Python生成器generator原理及用法解析
2020/07/20 Python
python进行OpenCV实战之画图(直线、矩形、圆形)
2020/08/27 Python
使用css3制作动感导航条示例
2014/01/26 HTML / CSS
VICHY薇姿英国官网:全球专业敏感肌护肤领先品牌
2017/07/04 全球购物
前台领班岗位职责
2013/12/04 职场文书
放飞梦想演讲稿
2014/05/05 职场文书
户外宣传策划方案
2014/05/25 职场文书
大学生就业协议书范本(适用于公司企业)
2014/10/07 职场文书
优秀员工自荐书
2015/03/06 职场文书
新闻稿格式范文
2015/07/18 职场文书
Oracle安装TNS_ADMIN环境变量设置参考
2021/11/01 Oracle
MySQL数据库如何查看表占用空间大小
2022/06/10 MySQL