如何避免PHP对象嵌套/创建限制? [英] How to Avoid PHP Object Nesting/Creation Limit?
问题描述
我有一个PHP的手工ORM,似乎是碰到一个对象限制,导致PHP崩溃。这是一个简单的脚本,会导致崩溃:
I've got a handmade ORM in PHP that seems to be bumping up against an object limit and causing php to crash. Here's a simple script that will cause crashes:
<?
class Bob
{
protected $parent;
public function Bob($parent)
{
$this->parent = $parent;
}
public function __toString()
{
if($this->parent)
return (string) "x " . $this->parent;
return "top";
}
}
$bobs = array();
for($i = 1; $i < 40000; $i++)
{
$bobs[] = new Bob($bobs[$i -1]);
}
?>
即使从命令行运行也会导致问题。有些箱子需要4万多件物品。我试过它在Linux / Appache(失败),但我的应用程序运行在IIS / FastCGI。在FastCGI上,这导致着名的FastCGI进程意外退出错误。
Even running this from the command line will cause issues. Some boxes take more than 40,000 objects. I've tried it on Linux/Appache (fail) but my app runs on IIS/FastCGI. On FastCGI this causes the famous "The FastCGI process exited unexpectedly" error.
显然,20k对象有点高,但崩溃与更少的对象,如果他们有数据和嵌套复杂性。
Obviously 20k objects is a bit high, but it crashes with far fewer objects if they have data and nested complexity.
快速CGI不是问题 - 我试过从命令行运行它。我试着将内存设置为真正高的 - 6,000MB和一些真正低的 - 24MB。如果我把它设置得足够低,我会得到分配的内存大小xxx字节耗尽的错误。
Fast CGI isn't the issue - I've tried running it from the command line. I've tried setting the memory to something really high - 6,000MB and to something really low - 24MB. If I set it low enough I'll get the "allocated memory size xxx bytes exhausted" error.
我认为它与被调用的函数的数量有关 - 某种类型的嵌套预防。我不认为我的ORM的嵌套是那么复杂,但也许是。我有一些很清楚的情况下,如果我只加载一个更多的对象,它死了,但加载在3秒以下,如果它的工作。
I'm thinking that it has to do with the number of functions that are called - some kind of nesting prevention. I didn't think that my ORM's nesting was that complicated but perhaps it is. I've got some pretty clear cases where if I load just ONE more object it dies, but loads in under 3 seconds if it works.
推荐答案
有趣的是,在我的环境中,看起来segfault发生在解构对象的时候循环运行良好。
Interestingly, in my environment, it appears that the segfault occurs when it comes time to deconstruct the objects -- code placed after the loop runs fine. It's only when PHP starts to shutdown that the segfault occurs.
你可以文件错误,但你可能会发现,PHP的维护者不会走出自己的方式来支持这种事情。我已经看到至少一个关于内存泄漏的错误报告,其中正式的响应本质上是Wontfix:内存在页面渲染后释放,所以这没有什么重要 - 有效地暗示外部使用简单
You could file a bug, but you may find that PHP's maintainers won't go out of their way to support this sort of thing. I've seen at least one bug report about a memory leak in which the official response was essentially "Wontfix: memory is released after the page is rendered, so this doesn't really matter" -- effectively implying that uses outside of the simple case of rapidly rendering a webpage and terminating aren't really supported.
经过5年的全职PHP开发,我得出了一个简单的规则:如果崩溃PHP,不要这样做。 PHP有它的局限性,如果你不推这些限制,你会发现自己最成功。
After 5 years of full-time PHP development, I've arrived at a simple rule: if it crashes PHP, don't do it. PHP has its limitations, and you'll find yourself most successful if you don't push those limits.
这意味着在PHP< = 5.2(它泄漏的内存像疯了)避免 create_function()
。您可以尝试使用 create_function()
来使用PHP,就像它是一种功能语言一样。
That means things like avoiding create_function()
in PHP <=5.2 (it leaks memory like crazy). You can try to use create_function()
to use PHP as if it were a functional language. It's not, and you'll find it fails miserably if you try to use it as such.
因此,如果PHP阻塞嵌套对象40000级深... don'嵌套对象40000级深。一个可能的选择是使用数组而不是对象 - 但是仍然听起来很可笑。
So if PHP chokes on nesting objects 40000 levels deep... don't nest objects 40000 levels deep. One possible alternative is using arrays instead of objects -- but that still sounds pretty heinous.
这篇关于如何避免PHP对象嵌套/创建限制?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!