PHP不能处理栈溢出吗?

4

当我尝试下面的PHP代码时,感到很惊讶:

function foo()
{
    foo();
}
foo();

我本来期望会收到“500:内部服务器错误”的提示。但实际上,连接立即被关闭(没有接收到任何字节),而日志文件显示Apache崩溃了。这是怎么回事?PHP中是否存在已知的bug?是否有一些配置选项我没注意到?因为每次意外堆栈溢出都导致进程崩溃,这是相当不可接受的。


1
可能编译器看到你的代码后想:“哦,天啊,这个人好聪明啊...让我一个人静静地呆着吧...” - F.P
1
毫无疑问。特别是因为PHP没有编译器。 :p - Vilx-
我认为崩溃不是优化的问题。另一方面,PHP应该如何更优雅地处理这样的情况? - innaM
5
当PHP看到像这样的东西时,你不应该指望它提供良好的错误信息:http://lorienshaw.net/hasselhoff.html - schnaader
就像我说的那样,它应该像处理其他未处理的运行时错误一样(比如未捕获的异常)。它应该给出一些错误信息(你可以说“堆栈溢出”吗?)并返回一个500的HTTP状态码。 - Vilx-
显示剩余2条评论
4个回答

5

太好了。迫不及待地等待生产升级到PHP 5.3。:P - Vilx-

2
避免使用递归函数,它们通常是一个坏主意。0 riiight:))) 它们是因为这是一个坏主意而发明的:))...。
我建议设置一个严格的上限来限制函数被调用的次数。不要使用全局变量(你可能需要调用更多递归函数,为什么要像这样污染全局变量呢?)。你可以为函数使用额外参数。
function a($param1, $param2, $depth=100){
  $depth--;
  if(!$depth==0) return error
}

2
这不是重点。当然,我可以使用许多自己的保障来编写代码。但是错误是不可避免的,迟早会出现StackOverflow。最有可能的情况是递归不是有意的,比如一个函数调用另一个函数,而后者又调用第一个函数。在这种情况下,一个不明确的段错误根本没有帮助。 - Vilx-
真的,如果使用 PHP 模块的调试版本,不知道会发生什么。默认情况下,任何溢出的应用程序都会生成 segfault 并退出...因为它是 segfault。必须向文件中添加特殊(缓慢)的调试代码来处理堆栈溢出,这可能是 PHP 解释器不处理它的原因。您还可以尝试使用 xdebug 和/或 suhosin。 - Quamis

1

摘自iBlog - Ilia Alshanetsky

Stack overflow. PHP does not have any internal stack protection choosing to rely upon the system stack without any protection. This means that if you have a recursive function or a method PHP will eventually crash.

function a() { a(); } a();

There are 2 solutions to this problem, 1 avoid using recursive functions they are generally a bad idea anyway, and if you MUST use them implement some counter using a global variable that would prevent the function from iterating itself more then X amount of time for values of X between 500 to 1000. The other solution involves using the xdebug extension that implements protection against stack overflows by defining a limit on how deep can recursive functions go via a php.ini value. This is a better solution in hosting environments where you have no control over the scripts that are being ran on the server.


1
关于xdebug的信息很好,但我要反驳你的说法,即递归函数是一个坏主意。是的,它们可能很棘手,但对于某些情况(如树遍历),它们是最有效的方法。 - dnagirl
其实这段代码完全是从别的地方拿来的,我本来想评论一下递归函数的问题。别误会,我知道递归的威力,只是不想修改这句引用。 - Cem Kalyoncu

0

来自链接文章的有趣引用:“避免使用递归函数,它们通常都不是一个好主意。” - innaM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接