<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>潘锦的空间 &#187; 递归函数</title>
	<atom:link href="https://www.phppan.com/tag/%e9%80%92%e5%bd%92%e5%87%bd%e6%95%b0/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.phppan.com</link>
	<description>SaaS SaaS架构 团队管理 技术管理 技术架构 PHP 内核 扩展 项目管理</description>
	<lastBuildDate>Sun, 10 May 2026 02:26:45 +0000</lastBuildDate>
	<language>zh-CN</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=3.9.40</generator>
	<item>
		<title>PHP中的函数嵌套层数限制</title>
		<link>https://www.phppan.com/2011/06/php-function-nesting-level/</link>
		<comments>https://www.phppan.com/2011/06/php-function-nesting-level/#comments</comments>
		<pubDate>Tue, 07 Jun 2011 01:09:19 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[xdebug]]></category>
		<category><![CDATA[递归函数]]></category>

		<guid isPermaLink="false">http://www.phppan.com/?p=1394</guid>
		<description><![CDATA[函数嵌套，这个名字有点纠结，也许不太好理解。一个比较常见的函数嵌套特例：递归函数，即函数自己嵌套自己。 一直以 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p style="text-indent: 2em;">函数嵌套，这个名字有点纠结，也许不太好理解。一个比较常见的函数嵌套特例：递归函数，即函数自己嵌套自己。 一直以为在PHP中不能有太多的函数嵌套，这是因为在以前某些时候不小心用到了递归，在递归的深度达到100时， 即函数嵌套的层数达到100时，程序会报一个 <strong>Fatal error</strong>。如下示例：</p>
<pre style="background-color: #333333; color: #ffffff; font: normal normal normal 13px/normal 'Bitstream Vera Sans Mono', 'DejaVu Sans Mono', 'Courier New', monospace; overflow-x: auto; overflow-y: auto; padding: 10px;"><span style="color: #cc7833;">function</span> rt<span style="color: #ffffff;">(</span><span style="color: #ffffff;">)</span> <span style="color: #ffffff;">{</span>
    <a style="color: #1299da; text-decoration: none;" href="http://www.php.net/static"><span style="color: #e2392d;">static</span></a> <span style="color: #6d9cbe;">$i</span><span style="color: #e0882f;">;</span>
    <a style="color: #1299da; text-decoration: none;" href="http://www.php.net/echo"><span style="color: #e2392d;">echo</span></a> <span style="color: #6d9cbe;">$i</span><span style="color: #e0882f;">++,</span> <span style="color: #56db3a;">'&lt;br /&gt;'</span><span style="color: #e0882f;">;</span>
    rt<span style="color: #ffffff;">(</span><span style="color: #ffffff;">)</span><span style="color: #e0882f;">;</span>
<span style="color: #ffffff;">}</span>
rt<span style="color: #ffffff;">(</span><span style="color: #ffffff;">)</span><span style="color: #e0882f;">;</span>
<a style="color: #1299da; text-decoration: none;" href="http://www.php.net/die"><span style="color: #e2392d;">die</span></a><span style="color: #ffffff;">(</span><span style="color: #ffffff;">)</span><span style="color: #e0882f;">;</span></pre>
<p style="text-indent: 2em;">在我的win7 + php5.3的环境下报错如下： Fatal error：Maximum function nesting level of &#8217;100&#8242; reached, aborting!</p>
<p style="text-indent: 2em;">一直以为是PHP本身的限制，直到某一天切换到liunx环境下以命令行的模式运行，发现，程序限入了死循环。 不同的环境下有不同的结果，为什么呢？好吧，我们直接在源码中查找报错信息，发现没有相关内容，直接debug整个执行过程，也没有在win下的报错。 什么原因？再次切换到win下，再次查找，发现在xdebug中看到了报错信息。在xdebug.c文件的1242行开始：</p>
<pre style="background-color: #333333; color: #ffffff; font: normal normal normal 13px/normal 'Bitstream Vera Sans Mono', 'DejaVu Sans Mono', 'Courier New', monospace; overflow-x: auto; overflow-y: auto; padding: 10px;">XG<span style="color: #ffffff;">(</span>level<span style="color: #ffffff;">)</span><span style="color: #e0882f;">++;</span>
<span style="color: #ff8400;">if</span> <span style="color: #ffffff;">(</span>XG<span style="color: #ffffff;">(</span>level<span style="color: #ffffff;">)</span> <span style="color: #e0882f;">==</span> XG<span style="color: #ffffff;">(</span>max_nesting_level<span style="color: #ffffff;">)</span><span style="color: #ffffff;">)</span> <span style="color: #ffffff;">{</span>
    php_error<span style="color: #ffffff;">(</span>E_ERROR<span style="color: #e0882f;">,</span> <span style="color: #99ff00;">"Maximum function nesting level of '%ld' reached,
         aborting!"</span><span style="color: #e0882f;">,</span> XG<span style="color: #ffffff;">(</span>max_nesting_level<span style="color: #ffffff;">)</span><span style="color: #ffffff;">)</span><span style="color: #e0882f;">;</span>
<span style="color: #ffffff;">}</span></pre>
<p style="text-indent: 2em;">这表示什么？之前的函数嵌套的层数限制是xdebug扩展加上的，为什么会有这个限制了呢？在xdebug中，xdebug中会记录每次函数调用， 包括嵌套的函数调用，函数调用中的内存，时间等值，这些值在分析程序性能时有大用。如果没有这个限制，当嵌套的层数太多，机器会内存耗尽。 如果这是一台生产环境的服务器，那么就会有部分服务不可用，当然生产环境下是不会添加这个扩展的。但是在多人共用的开发服务器上就可能有这个扩展， 如果因为一个开发人员的程序错误导致机器不可用，从而使所有的开发人员不能工作，我想这也许是添加限制的原因吧。</p>
<p style="text-indent: 2em;">如果我们需要把这个限制的层数加大，怎么办呢？改源码，重新编译xdebug扩展？不需要，在xdebug的配置项中有一项叫做xdebug.max_nesting_level， 默认情况下，在php.ini中这个配置项是被注释了的，去掉注释，将这个值成你所需要的值，200？不够，那500吧，但是这个值还是不要太大， 如果递归太多，对程序的性能有很大的影响，此时，以栈的形式实现递归或者用循环替换递归会是一个更好的方案， 如：斐波那契数列(Fibonacci)的实现，用循环来实现会更快。</p>
<p style="text-indent: 2em;">结论：<strong>PHP本身的函数嵌套是没有限制的，如果说有限制，也是最大栈空间的限制。</strong></p>
<p style="text-indent: 2em;">感谢<a href="http://www.laruence.com/" target="_blank">鸟哥</a>指出结论的错误，有些想当然了。</p>
<p style="text-indent: 2em;"><strong><br />
</strong></p>
]]></content:encoded>
			<wfw:commentRss>https://www.phppan.com/2011/06/php-function-nesting-level/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
