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写的MySQL数据库用户认证系统代码
Mar 22 PHP
php 正则 过滤html 的超链接
Jun 02 PHP
PHP删除HTMl标签的三种解决方法
Jun 30 PHP
用Zend Studio+PHPnow+Zend Debugger搭建PHP服务器调试环境步骤
Jan 19 PHP
在PHP模板引擎smarty生成随机数的方法和math函数详解
Apr 24 PHP
ThinkPHP的URL重写问题
Jun 22 PHP
基于PHP的简单采集数据入库程序
Jul 30 PHP
PHP中的事务使用实例
May 26 PHP
php简单图像创建入门实例
Jun 10 PHP
php ajax异步读取rss文档数据
Mar 29 PHP
highchart数据源纵轴json内的值必须是int(详解)
Feb 20 PHP
php设计模式之模板模式实例分析【星际争霸游戏案例】
Mar 24 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 杂谈《重构-改善既有代码的设计》之五 简化函数调用
2012/05/07 PHP
Ajax+PHP快速上手及简单应用说明
2013/07/24 PHP
php微信公众号开发之欢迎老朋友
2018/10/20 PHP
javascript下判断一个元素是否存在的代码
2010/03/05 Javascript
javascript去掉前后空格的实例
2013/11/07 Javascript
javascript截取字符串小结
2015/04/28 Javascript
Javascript中的作用域和上下文深入理解
2015/07/03 Javascript
jquery实现红色竖向多级向右展开的导航菜单效果
2015/08/31 Javascript
理解javascript异步编程
2016/01/27 Javascript
javascript求日期差的方法
2016/03/02 Javascript
Angularjs中使用Filters详解
2016/03/11 Javascript
jQuery.datatables.js插件用法及api实例详解
2016/10/28 Javascript
详解Vue中一种简易路由传参办法
2017/09/15 Javascript
JavaScript运行原理分析
2018/02/09 Javascript
详解vue组件开发脚手架
2018/06/15 Javascript
深入了解Python数据类型之列表
2016/06/24 Python
Python基于QRCode实现生成二维码的方法【下载,安装,调用等】
2017/07/11 Python
python3 破解 geetest(极验)的滑块验证码功能
2018/02/24 Python
python实现随机梯度下降法
2020/03/24 Python
tensorflow入门:TFRecordDataset变长数据的batch读取详解
2020/01/20 Python
python 如何用urllib与服务端交互(发送和接收数据)
2021/03/04 Python
澳大利亚网上玩具商店:Mr Toys Toyworld
2018/03/25 全球购物
英国在线定制百叶窗网站:Swift Direct Blinds
2020/02/25 全球购物
惠普新加坡官方商店:HP Singapore
2020/04/17 全球购物
Java的基础面试题附答案
2016/01/10 面试题
网站开发实习生的自我评价
2013/12/11 职场文书
展会邀请函范文
2014/01/26 职场文书
车队司机自我鉴定
2014/03/02 职场文书
教师一岗双责责任书
2014/04/16 职场文书
社团活动总结
2014/04/28 职场文书
建筑施工安全生产责任书
2014/07/22 职场文书
职工年度考核评语
2014/12/31 职场文书
人工作失职检讨书
2015/05/05 职场文书
2016猴年开门红标语口号
2015/12/26 职场文书
六年级语文教学反思
2016/03/03 职场文书
CSS3点击按钮圆形进度打钩效果的实现代码
2021/03/30 HTML / CSS