如何避免PHP对象嵌套/创建限制? [英] How to Avoid PHP Object Nesting/Creation Limit?

查看:216
本文介绍了如何避免PHP对象嵌套/创建限制?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆