【问题标题】:How to Avoid PHP Object Nesting/Creation Limit?如何避免 PHP 对象嵌套/创建限制?
【发布时间】:2010-04-06 00:29:29
【问题描述】:

我在 PHP 中有一个手工制作的 ORM,它似乎遇到了对象限制并导致 php 崩溃。这是一个会导致崩溃的简单脚本:

<?
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]);
}    
?>

即使从命令行运行它也会导致问题。有些盒子可以容纳超过 40,000 个物体。我已经在 Linux/Apache 上尝试过(失败),但我的应用程序在 IIS/FastCGI 上运行。在 FastCGI 上,这会导致著名的“FastCGI 进程意外退出”错误。

显然 20k 个对象有点高,但如果对象有数据和嵌套复杂性,它会崩溃的对象要少得多。

快速 CGI 不是问题 - 我已经尝试从命令行运行它。我尝试将内存设置为非常高的值 - 6,000MB 和非常低的值 - 24MB。如果我将它设置得足够低,我会得到“分配的内存大小 xxx 字节用尽”错误。

我认为这与被调用的函数的数量有关 - 某种嵌套预防。我不认为我的 ORM 的嵌套有那么复杂,但也许确实如此。我有一些非常清楚的案例,如果我再加载一个对象,它就会死掉,但如果它有效,它会在 3 秒内加载。

【问题讨论】:

    标签: php crash object


    【解决方案1】:

    有趣的是,在我的环境中,似乎在解构对象时会发生段错误——放置在循环之后的代码运行良好。只有当 PHP 开始关闭时才会发生段错误。

    您可以file a bug,但您可能会发现 PHP 的维护人员不会竭尽全力支持这种事情。我已经看到至少一个关于内存泄漏的错误报告,其中官方响应基本上是“Wontfix:在页面呈现后释放内存,所以这并不重要”——实际上暗示了简单之外的使用并不真正支持快速呈现网页并终止的情况。

    经过 5 年的全职 PHP 开发,我得出了一个简单的规则:如果 PHP 崩溃了,不要这样做。 PHP 有其局限性,如果您不突破这些限制,您会发现自己是最成功的。

    这意味着在 PHP create_function()(它会疯狂地泄漏内存)。您可以尝试使用create_function() 来使用 PHP,就好像它是一种函数式语言一样。它不是,如果你尝试这样使用它,你会发现它会失败。

    因此,如果 PHP 在嵌套 40000 层深的对象时窒息...不要嵌套 40000 层深的对象。一种可能的替代方法是使用数组而不是对象——但这听起来仍然令人发指。

    【讨论】:

    • “医生,我这样做这个会很痛!” -- “那就不要那样做。”
    猜你喜欢
    • 1970-01-01
    • 2018-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-27
    相关资源
    最近更新 更多