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 相关文章推荐
用 PHP5 轻松解析 XML
Dec 04 PHP
PHP写MySQL数据 实现代码
Jun 15 PHP
php str_pad() 将字符串填充成指定长度的字符串
Feb 23 PHP
PHP中strtotime函数使用方法分享
Jan 10 PHP
PHP中header和session_start前不能有输出原因分析
Jan 11 PHP
php实现扫描二维码根据浏览器类型访问不同下载地址
Oct 15 PHP
PHP+MySQL修改记录的方法
Jan 21 PHP
十幅图告诉你什么是PHP引用
Feb 22 PHP
php简单图像创建入门实例
Jun 10 PHP
PHP封装的数据库保存session功能类
Jul 11 PHP
php爬取天猫和淘宝商品数据
Feb 23 PHP
php回调函数处理数组操作示例
Apr 13 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
一个程序下载的管理程序(三)
2006/10/09 PHP
解析argc argv在php中的应用
2013/06/24 PHP
mac下安装nginx和php
2013/11/04 PHP
PHP简单实现数字分页功能示例
2016/08/24 PHP
YII框架行为behaviors用法示例
2019/04/26 PHP
代码生成器 document.write()
2007/04/15 Javascript
用js实现层随着内容大小动态渐变改变 推荐
2009/12/19 Javascript
jQuery EasyUI API 中文文档 - Form表单
2011/10/06 Javascript
深入理解JavaScript系列(1) 编写高质量JavaScript代码的基本要点
2012/01/15 Javascript
AngularJS入门教程之Hello World!
2014/12/06 Javascript
基于jquery实现select选择框内容左右移动添加删除代码分享
2015/08/25 Javascript
使用PHP+JavaScript将HTML页面转换为图片的实例分享
2016/04/18 Javascript
批量下载对路网图片并生成html的实现方法
2016/06/07 Javascript
微信小程序 Image API实例详解
2016/09/30 Javascript
浅谈react前后端同构渲染
2017/09/20 Javascript
微信小程序上传图片功能(附后端代码)
2020/06/19 Javascript
详解Angular5/Angular6项目如何添加热更新(HMR)功能
2018/10/10 Javascript
微信小程序事件对象中e.target和e.currentTarget的区别详解
2019/05/08 Javascript
vue props 单项数据流实例分享
2020/02/16 Javascript
Python NumPy库安装使用笔记
2015/05/18 Python
Python的装饰器使用详解
2017/06/26 Python
浅谈python可视化包Bokeh
2018/02/07 Python
python3.x+pyqt5实现主窗口状态栏里(嵌入)显示进度条功能
2019/07/04 Python
基于python 取余问题(%)详解
2020/06/03 Python
使paramiko库执行命令时在给定的时间强制退出功能的实现
2021/03/03 Python
STAY JAPAN台湾:预订日本民宿
2018/07/22 全球购物
建筑装饰学院室内设计专业个人自我评价
2013/12/07 职场文书
党员的自我评价范文
2014/01/02 职场文书
小露珠教学反思
2014/04/30 职场文书
环境工程专业自荐信范文
2014/06/24 职场文书
中学生纪念九一八事变演讲稿
2014/09/14 职场文书
教师自我剖析材料范文
2014/09/30 职场文书
2014年四风个人对照检查及整改措施
2014/10/28 职场文书
遗失说明具结保证书
2015/02/26 职场文书
先进基层党组织主要事迹材料
2015/11/03 职场文书
vue实现简单数据双向绑定
2021/04/28 Vue.js