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学习 运算符与运算符优先级
Jun 15 PHP
PHP+XML 制作简单的留言本 图文教程
Nov 02 PHP
php实现文件下载(支持中文文名)
Dec 04 PHP
php缩小png图片不损失透明色的解决方法
Dec 25 PHP
php获取CSS文件中图片地址并下载到本地的方法
Dec 02 PHP
详细解读PHP中接口的应用
Aug 12 PHP
PHP批量去除BOM头内容信息代码
Mar 11 PHP
Smarty保留变量用法分析
May 23 PHP
注释PHP和html混合代码的小技巧(分享)
Nov 03 PHP
PHP实现表单提交时去除斜杠的方法
Dec 26 PHP
利用php的ob缓存机制实现页面静态化方法
Jul 09 PHP
Laravel5.5 实现后台管理登录的方法(自定义用户表登录)
Sep 30 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
推荐Discuz!5的PHP代码高亮显示与实现可运行代码
2007/03/15 PHP
PHP定义字符串的四种方式详解
2018/02/06 PHP
解决Laravel自定义类引入和命名空间的问题
2019/10/15 PHP
Laravel ORM 数据model操作教程
2019/10/21 PHP
Three.js源码阅读笔记(Object3D类)
2012/12/27 Javascript
javascript+HTML5自定义元素播放焦点图动画
2016/02/21 Javascript
全面解析Bootstrap表单样式的使用
2016/09/09 Javascript
全屏滚动插件fullPage.js使用实例解析
2016/10/21 Javascript
BootStrap中关于Select下拉框选择触发事件及扩展
2016/11/22 Javascript
详解基于node的前端项目编译时内存溢出问题
2017/08/01 Javascript
基于Bootstrap框架菜鸟入门教程(推荐)
2017/09/17 Javascript
JS动态添加元素及绑定事件造成程序重复执行解决
2017/12/07 Javascript
tween.js缓动补间动画算法示例
2018/02/13 Javascript
Vue项目中最新用到的一些实用小技巧
2018/11/06 Javascript
vue scroll滚动判断的实现(是否滚动到底部、滚动方向、滚动节流、获取滚动区域dom元素)
2020/06/11 Javascript
[01:02:05]LGD vs Mineski 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
Python映射拆分操作符用法实例
2015/05/19 Python
python基础教程项目二之画幅好画
2018/04/02 Python
python 实现对文件夹中的图像连续重命名方法
2018/10/25 Python
python实现微信自动回复及批量添加好友功能
2019/07/03 Python
Pandas中DataFrame的分组/分割/合并的实现
2019/07/16 Python
python常见字符串处理函数与用法汇总
2019/10/30 Python
python调用私有属性的方法总结
2020/07/24 Python
HTML5 Canvas绘制文本及图片的基础教程
2016/03/14 HTML / CSS
HTML5中Localstorage的使用教程
2015/07/09 HTML / CSS
New Balance美国官网:运动鞋和健身服装
2017/04/11 全球购物
eDreams加拿大:廉价航班、酒店和度假
2019/03/29 全球购物
汉语言文学毕业生自荐信范文
2014/03/24 职场文书
户籍证明书标准模板
2014/09/10 职场文书
期末考试复习计划
2015/01/19 职场文书
采购部年度工作总结
2015/08/13 职场文书
2019财务管理制度最新范本!
2019/07/09 职场文书
详解PHP Swoole与TCP三次握手
2021/05/27 PHP
python 爬取京东指定商品评论并进行情感分析
2021/05/27 Python
python基础之类方法和静态方法
2021/10/24 Python
Java实现扫雷游戏详细代码讲解
2022/05/25 Java/Android