PHP 中“致命错误: 达到最大函数嵌套级别‘100’,终止!”的解决方案

我已经创建了一个函数来查找 html 文件中的所有 URL,并对链接到所发现的 URL 的每个 html 内容重复相同的过程。这个函数是递归的,可以无休止地运行。但是,我通过设置一个全局变量来限制递归,这个全局变量会导致递归在100次递归之后停止。

然而,php 返回这个错误:

致命错误: 达到“100”的最大函数嵌套级别, 中止 D: wamp www Crawler1 simplehtmldom _ 1 _ 5 simple _ html _ dom.php on line 1355

ERROR

我在这里找到了一个解决方案: 增加嵌套函数调用限制,但这在我的情况下不起作用。

我从上面提到的链接中引用了一个答案,请考虑一下。

”您是否安装了 Zend、 IonCube 或 xDebug? 如果是,那么您可能就是从这里得到这个错误的。

几年前我遇到过这种情况,最后是 Zend 把这个限制放在了那里,而不是 PHP。当然,删除它会让你超过100次迭代,但你最终会达到内存限制。”

有没有办法提高 PHP 中函数嵌套的最大级别

315703 次浏览

您可以尝试通过实现并行工作(如集群计算)而不是增加嵌套函数调用的数量来减少嵌套。

例如: 您定义一个有限数量的插槽(例如100) ,并监视分配给每个/其中一些插槽的“ worker”数量。如果有空位,你就把等待的工人放进去。

您可以将递归代码转换为迭代代码,以模拟递归。这意味着,当您到达一个链接时,必须将当前状态(url、 document、 document 中的位置等)推入一个数组,并在该链接完成时将其从数组中弹出。

与其使用递归函数调用,不如使用队列模型来展开结构。

$queue = array('http://example.com/first/url');
while (count($queue)) {
$url = array_shift($queue);


$queue = array_merge($queue, find_urls($url));
}


function find_urls($url)
{
$urls = array();


// Some logic filling the variable


return $urls;
}

有不同的方法来处理。如果您需要了解所经过的起源或路径,则可以跟踪更多信息。还有一些分布式队列可以处理类似的模型。

一个简单的解决方案解决了我的问题,我只是注释了这句话:

zend_extension = "d:/wamp/bin/php/php5.3.8/zend_ext/php_xdebug-2.1.2-5.3-vc9.dll

在我的 php.ini文件里。这个扩展将堆栈限制为 100,所以我禁用了它。递归函数现在正如预期的那样工作。

增加 php.inixdebug.max_nesting_level的值

另一个解决方案是在 php.ini 中添加 xdebug.max_nesting_level = 200

可能是因为 xdebug。

尝试在 “ php.ini”中注释以下行并重新启动服务器以重新加载 PHP。

";xdebug.max_nesting_level"

从命令行检查递归:

php -r 'function foo() { static $x = 1; echo "foo ", $x++, "\n"; foo(); } foo();'

如果结果 > 100,则检查内存限制;

尝试查看/etc/php5/config.d/,看看是否有一个名为 xdebug. ini 的文件

Max _ nesting _ level 默认为100

如果未在该文件中设置,请添加:

xdebug.max_nesting_level=300

看起来像这样

xdebug.remote_enable=on
xdebug.remote_handler=dbgp
xdebug.remote_host=localhost
xdebug.remote_port=9000
xdebug.profiler_enable=0
xdebug.profiler_enable_trigger=1
xdebug.profiler_output_dir=/home/drupalpro/websites/logs/profiler
xdebug.max_nesting_level=300

然后,您可以使用 @ Andrey’s测试之前和之后作出这个更改,看看是否工作。

php -r 'function foo() { static $x = 1; echo "foo ", $x++, "\n"; foo(); } foo();'

与禁用 xdebug 不同,您可以设置更高的限制,如

Max _ nesting _ level = 500

您还可以修改 modfier.debug _ print _ var.php 中的{ debug }函数,以便将其递归限制为对象。

在第45行之前:

$results .= '<br>' . str_repeat('&nbsp;', $depth * 2)
. '<b> -&gt;' . strtr($curr_key, $_replace) . '</b> = '
. smarty_modifier_debug_print_var($curr_val, ++$depth, $length);

之后:

$max_depth = 10;
$results .= '<br>' . str_repeat('&nbsp;', $depth * 2)
. '<b> -&gt;' . strtr($curr_key, $_replace) . '</b> = '
. ($depth > $max_depth ? 'Max recursion depth:'.(++$depth) : smarty_modifier_debug_print_var($curr_val, ++$depth, $length));

这样,Xdebug 仍然可以正常工作: 限制 var _ dump 中的递归深度等等。 因为这是一个聪明的问题,而不是 Xdebug 的问题!

在您的例子中,爬虫实例肯定对跟踪错误和调试信息有更多的 Xdebug 限制。

但是,在其他情况下,像 PHP 或像 CodeIgniter 库这样的核心文件中的错误也会产生这样的情况,即使您增加了 x-debug 级别的设置,它也不会消失。

因此,请仔细研究您的代码:)。

我的情况是这样的。

我有一个服务类,它是 CodeIgniter 中的库,里面有一个这样的函数。

 class PaymentService {


private $CI;


public function __construct() {


$this->CI =& get_instance();


}


public function process(){
//lots of Ci referencing here...
}

我的控制器如下:

$this->load->library('PaymentService');
$this->process_(); // see I got this wrong instead  it shoud be like

由于输入错误,最后一行的函数调用是错误的,应该是如下所示:

$this->Payment_service->process(); //the library class name

然后我不断得到超出错误消息。但是我禁用了 XDebug,但是没有帮助。无论如何,请检查您的类名称或正确的函数调用代码。

Php.ini:

Max _ neting _ level = -1

我不能完全确定该值是否会溢出并达到 -1,但它要么永远不会达到 -1,要么将 max _ nest _ level 设置得相当高。

也可以直接在 php 中修复这个问题,例如在项目的配置文件中。

ini_set('xdebug.max_nesting_level', 200);

进入 php.ini 配置文件并修改以下代码行:

xdebug.max_nesting_level=100

比如:

xdebug.max_nesting_level=200

我有一个错误,当我安装很多插件所以错误100显示,包括我安装的最后一个插件的位置,我安装的 C: wamp www 我的网站 wp-content 插件“ ...”所以我删除了这个插件文件夹在 C: 驱动器然后一切恢复正常。我认为我必须限制插件的数量,我安装或已经激活。祝你好运,希望能有所帮助

在 Ubuntu 上使用 PHP 5.59:
必须:

/etc/php5/cli/conf. d

在这个目录中找到你的 Xdebug. ini,在我的例子中是 20-xdebug. ini

加上这一行

Max _ nesting _ level = 200


或者这个

Max _ neting _ level = -1

将其设置为 -1,您就不必担心更改嵌套级别的值。

`

如果你在使用 Laravel,那就这么做

composer update

这应该是工作。

我在 Cloud9上使用 WordPress 时遇到了这个问题。原来是 W3缓存插件。我关闭了插件,它工作正常。

另一种解决方案,如果您在 CLI (cmd)中运行 php 脚本

在本例中,需要编辑的 php.ini 文件是不同的。在我的 WAMP 安装中,命令行中加载的 php.ini 文件是:

\wamp\bin\php\php5.5.12\php.ini

而不是 wamp bin apache apache2.4.9 bin php.ini,它在从浏览器运行 php 时加载

<?php
ini_set('xdebug.max_nesting_level', 9999);
... your code ...

另外,把9999改成你想要的任何号码。

我也有同样的问题,我这样解决了:

  • 打开 MySQL my.ini 文件
  • 在[ mysqld ]部分中,添加以下行: inodb _ force _ Recovery = 1
  • 保存文件并尝试启动 MySQL
  • 删除刚才添加的那一行,然后保存

在开发过程中也偶然发现了这个 bug。

然而,在我的例子中,它是由相互调用的函数的底层循环引起的——这是开发过程中持续迭代的结果。

为了以后的搜索引擎参考-我的日志提供给我的确切错误是:

Exception: Maximum function nesting level of '256' reached, aborting!

如果,就像我的情况一样,给出的答案不能解决你的问题,确保你不会不小心按照以下简化的情况做一些事情:

function foo(){
// Do something
bar();
}


function bar(){
// Do something else
foo();
}

在这种情况下,即使您设置了 ini_set('xdebug.max_nesting_level', 9999);,它仍然会在您的日志中打印出相同的错误消息。