我遇到的问题很奇怪。 在执行递归循环时会发生这种情况。 使用for循环或任何其他迭代执行相同任务时,不会发生这种情况。
在?21 000次以下递归调用函数时,一切正常。 超过此数字时会出现问题。
我的工作代码:
foo();
function foo($i = 1) {
if ($i > 20000) {
return;
}
echo $i . '
';
foo($i + 1);
return;
}
输出:... 199981999920000
不起作用的代码:
foo();
function foo($i = 1) {
if ($i > 30000) { // Or any number above ~21000
return;
}
echo $i . '
';
foo($i + 1);
return;
}
输出:... 134931349413最后一行在数字中间停止。
在某些情况下,它只是向服务器发送一个空响应。
我正在PHP版本5.6.10的Ubuntu上使用apache2服务器。 使用Xampp时,会发生相同的问题,只是数字略有不同。
听起来像是内存问题。尝试更改最大内存设置,重新启动Apache,然后再次运行代码。
在现实生活中是否需要30K递归调用?听起来像简单的循环确实可以在这里更有效地解决问题。
每个脚本允许使用多少内存?我认为默认值为128,因此您可能需要将其更改为256甚至更高。检查您的PHP ini是否有" memory_limit"
增加xdebug.max_nesting_level。在此处检查答案stackoverflow.com/questions/17488505/
那执行时间呢?还是输出缓冲区?
调用堆栈也有限制
@kdlcruz我现在没有xdebug,所以不能成为问题
在将memory_limit设置为64M的情况下,我进入了278518。执行时间小于2秒。您是否尝试过使用error_reporting = E_ALL并观看error.log文件? (用于复制:哪个版本的ubuntu?)
@ frz3993 20000个循环的执行时间约为0.02秒。我认为那不是最糟糕的
@VolkerK Ubuntu版本是14.04.2 LTS。 Havent看了我的error.log。现在要做。
出于安全考虑:我的意思是在php.ini中由error_log=....指令指定的文件;-)
@VolkerK检查了error_log=...指定的我的文件,但其中没有任何相关内容。
我怀疑它停止在上述数字中间,仅打印13的原因是因为当您的代码以过多的递归溢出堆栈时,其余输出已被缓冲并且从未发送过。尝试在echo语句之后添加ob_flush()以获取完整的输出。
在大多数当前流行的编程语言(包括PHP)中,函数可以执行多少递归是有限制的。这不是硬性限制;根据程序的状态,可以递归调用数以万计的深度,也可以仅数个深度。因此,实现像示例这样的深度递归函数并不安全,并且程序将崩溃。请参阅PHP用户定义函数文档底部的注释:
Recursive function/method calls with over 100–200 recursion levels can smash the stack and cause a termination of the current script.
每次调用函数时,程序必须在开始执行该函数之前记录执行的位置,因此它知道在函数返回后再次从何处开始执行。存储此信息的空间非常有限,因此,如果您同时有太多的函数调用,它将耗尽空间,并且程序将崩溃。此信息以及大量其他信息都存储在堆栈中,当堆栈中的空间用完时,这称为堆栈溢出或粉碎堆栈。
某些语言实现了称为尾部调用优化的功能,该功能允许在适当的情况下进行无限递归。功能语言通常支持此功能,例如Scheme和ML。但是,如PHP是否优化尾部递归?中所述,PHP不能。