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

查看:33
本文介绍了如何避免 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]);
}    
?>

即使从命令行运行它也会导致问题.有些盒子可以容纳超过 40,000 个物体.我已经在 Linux/Apache 上尝试过(失败),但我的应用程序在 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/Apache (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.

推荐答案

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

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 层深的对象时窒息...不要嵌套 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天全站免登陆