我创建了一个查找html文件中所有URL的函数,并为链接到发现的URL的每个html内容重复相同的过程。该函数是递归的,可以无休止地继续。但是,我通过设置一个全局变量来限制递归,这导致递归在100次递归后停止。
但是,php会返回此错误:
致命错误:达到最大功能嵌套级别'100', 中止!在 D:\ wamp \ www \ crawler1 \ simplehtmldom_1_5 \ simple_html_dom.php上线 1355
我在这里找到了一个解决方案:Increasing nesting function calls limit但这不符合我的情况。
我引用了上述链接中的一个答案。请考虑一下。
“您是否安装了Zend,IonCube或xDebug?如果是这样,那可能是您收到此错误的地方。
几年前我遇到过这个问题,结果是Zend把那个限制放在那里,而不是PHP。当然,删除它会让你超过100次迭代,但最终会达到内存限制。“
有没有办法在PHP中增加最大函数嵌套级别
答案 0 :(得分:136)
增加php.ini
xdebug.max_nesting_level
的值
答案 1 :(得分:54)
一个简单的解决方案解决了我的问题。我刚评论过这一行:
zend_extension = "d:/wamp/bin/php/php5.3.8/zend_ext/php_xdebug-2.1.2-5.3-vc9.dll
在我的php.ini
文件中。此扩展将堆栈限制为100
,因此我禁用了它。递归函数现在正如预期的那样工作。
答案 2 :(得分:44)
不是进行递归函数调用,而是使用队列模型来展平结构。
$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;
}
有不同的方法来处理它。如果您需要了解所遍历的原点或路径,您可以跟踪更多信息。还有一些分布式队列可以使用类似的模型。
答案 3 :(得分:40)
另一个解决方案是在php.ini
中添加xdebug.max_nesting_level = 200
答案 4 :(得分:23)
您可以设置上限,例如
,而不是禁用xdebugxdebug.max_nesting_level = 500
答案 5 :(得分:17)
也可以直接在php中修复此问题,例如在项目的配置文件中。
ini_set('xdebug.max_nesting_level', 200);
答案 6 :(得分:12)
可能是因为xdebug而发生的。
尝试在“php.ini”中评论以下行,然后重新启动服务器以重新加载PHP。
";xdebug.max_nesting_level"
答案 7 :(得分:12)
尝试查看/etc/php5/conf.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();'
答案 8 :(得分:12)
在Ubuntu上使用PHP 5.59:
得到了`:
/etc/php5/cli/conf.d
在该目录中找到 xdebug.ini ,在我的情况下是 20-xdebug.ini
并添加此行`
xdebug.max_nesting_level = 200
或者
xdebug.max_nesting_level = -1
将其设置为-1,您不必担心更改嵌套级别的值。
`
答案 9 :(得分:7)
的php.ini:
xdebug.max_nesting_level = -1
我不完全确定该值是否会溢出并达到-1,但它永远不会达到-1,或者它会将max_nesting_level设置得相当高。
答案 10 :(得分:6)
您可以将递归代码转换为迭代代码,模拟递归。这意味着当您到达链接时,必须将当前状态(网址,文档,文档中的位置等)推送到数组中,并在此链接完成时将其从数组中弹出。
答案 11 :(得分:6)
您可以尝试通过实现并行工作(例如在集群计算中)来摆动嵌套,而不是增加嵌套函数调用的数量。
例如:您定义有限数量的插槽(例如100)并监控分配给每个/部分插槽的“工作人员”的数量。如果任何插槽空闲,您可以将等待的工作人员“放入其中”。
答案 12 :(得分:5)
从命令行检查递归:
php -r 'function foo() { static $x = 1; echo "foo ", $x++, "\n"; foo(); } foo();'
如果结果> 100然后检查内存限制;
答案 13 :(得分:3)
如果您正在使用Laravel,请执行
composer update
这应该可行。
答案 14 :(得分:2)
在开发过程中也偶然发现了这个错误。
但是,在我的情况下,它是由相互调用的函数的底层循环引起的 - 作为开发过程中不断迭代的结果。
供搜索引擎将来参考 - 我的日志提供给我的确切错误是:
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);
,它仍会在您的日志中打印出相同的错误消息。
答案 15 :(得分:2)
<?php
ini_set('xdebug.max_nesting_level', 9999);
... your code ...
P.S。将9999更改为您想要的任何数字。
答案 16 :(得分:0)
我在安装许多插件时出错了所以错误100显示包含我安装的最后一个插件的位置C:\ wamp \ www \ mysite \ wp-content \ plugins \“...”所以我删除C:驱动器上的这个插件文件夹,然后一切都恢复正常。我想我必须限制我安装或已激活插件的数量。运气好我希望它有所帮助
答案 17 :(得分:0)
我在cloud9上遇到了WordPress的这个问题。原来它是W3 Caching插件。我禁用了该插件,它工作正常。
答案 18 :(得分:0)
在这种情况下,需要编辑的php.ini文件是不同的。在我的WAMP安装中,在命令行中加载的php.ini文件是:
\wamp\bin\php\php5.5.12\php.ini
而不是从浏览器运行php时加载的\ wamp \ bin \ apache \ apache2.4.9 \ bin \ php.ini
答案 19 :(得分:0)
在你的情况下,它肯定是爬虫实例有更多的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但没有帮助。无论如何,请检查您的班级名称或代码,以便正确调用函数。
答案 20 :(得分:0)
我遇到了同样的问题,我很喜欢这样:
打开MySQL my.ini文件
在[mysqld]部分中,添加以下行:innodb_force_recovery = 1
保存文件,然后尝试启动MySQL
删除刚刚添加的那一行并保存
答案 21 :(得分:0)
您还可以修改modifier.debug_print_var.php中的{debug}函数,以限制其递归到对象中。
第45行,之前:
$results .= '<br>' . str_repeat(' ', $depth * 2)
. '<b> ->' . strtr($curr_key, $_replace) . '</b> = '
. smarty_modifier_debug_print_var($curr_val, ++$depth, $length);
之后:
$max_depth = 10;
$results .= '<br>' . str_repeat(' ', $depth * 2)
. '<b> ->' . 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!