我遇到的问题很奇怪。它发生在做递归循环的时候。当使用for循环或任何其他迭代执行相同的任务时,不会发生这种情况。
当递归调用一个函数低于~ 21000次时,一切都正常。
当超过此数值时,会出现问题。工作代码:
foo();
function foo($i = 1) {
if ($i > 20000) {
return;
}
echo $i . '<br/>';
foo($i + 1);
return;
}
输出:
19998
19999
20000
不工作的代码:
foo();
function foo($i = 1) {
if ($i > 30000) { // Or any number above ~21000
return;
}
echo $i . '<br/>';
foo($i + 1);
return;
}
输出:
…
13493
13494
13
最后一行停在号码中间。在某些情况下,它只向服务器发送一个空响应。
我在Ubuntu上使用apache2服务器,PHP版本5.6.10。使用Xampp,也会出现同样的问题,只是数字有点不同。
在包括PHP在内的大多数当前流行的编程语言中,函数可以执行多少递归都是有限制的。这不是一个硬性限制;根据程序的状态,它可以是数万个深度的递归调用,也可以是几个深度的递归调用。因此,像您的示例那样实现深度递归函数是不安全的,并且您的程序将崩溃。请参阅PHP用户定义函数文档底部的注释:
超过100-200个递归级别的递归函数/方法调用可能会破坏堆栈并导致当前脚本终止。
每次调用函数时,程序必须在开始执行函数之前记录执行位置,以便在函数返回后知道从哪里开始再次执行。存储这些信息的空间是有限的,所以如果同时有太多的函数调用,就会耗尽空间,程序就会崩溃。这个信息,连同一堆其他信息,被存储在堆栈中,当你用完堆栈中的空间时,它被称为堆栈溢出或粉碎堆栈。
一些语言实现了一个被称为尾部调用优化的特性,它允许在适当的情况下无限递归。函数式语言通常支持这一点,如Scheme和ML。然而,PHP不支持,如PHP是否优化尾部递归?