How to avoid restrictions on nesting / creating PHP objects?

I have a hand-crafted ORM in PHP that seems to collide with an object constraint and cause php to crash. Here is a simple script that will crash:

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

      

Even running this from the command line will cause problems. Some boxes contain over 40,000 items. I tried this on Linux / Apache (crashing), but my application is running on IIS / FastCGI. In FastCGI, this results in a "Fast termination of FastCGI process" error.

Obviously 20k objects are a little high, but fail with much fewer objects if they have data and nesting complexity.

Fast CGI is not a problem - I tried running it from the command line. I tried to set the memory to something really high - 6,000 MB and to something really low - 24 MB. If I set it low enough, I get a "xxx memory size freed" error.

I think this is due to the number of functions that are called - some kind of protection from nesting. I didn't think my ORM socket was that complicated, but maybe it is. I have pretty clear-cut cases where I only load one object it dies, but it loads in less than 3 seconds if it works.

+1


source to share


1 answer


Interestingly, in my environment, it seems that the segfault occurs when it comes time to deconstruct objects - the code placed after the loop runs fine. This only happens when PHP starts shutting down, which is a segfault.

You might create a buggy file , but you might find that PHP proponents won't get in the way of supporting this sort of thing.I've seen at least one memory leak bug report where the official answer was essentially "Wontfix: memory released after mapping page, so it doesn't really matter "- actually implying that use outside of the simple case of fast web page rendering and completion is not supported.

After 5 years of PHP development, I've come to a simple rule of thumb: if it crashes PHP, don't do it. PHP has its limitations and you will be most successful if you don't hit those limitations.



This means you are avoiding create_function()

in PHP <= 5.2 (it leaks memory like crazy). You can use create_function()

PHP to use it as if it were a functional language. It is not, and you will find that it fails if you try to use it as such.

So if PHP throttles on nested objects 40,000 levels deep ... objects 40,000 levels deep are not nested. One possible alternative is to use arrays instead of objects, but that still sounds pretty disgusting.

+4


source







All Articles