Как избежать ограничения вложенности / создания объектов PHP? - PullRequest
1 голос
/ 06 апреля 2010

У меня есть ручной ORM в PHP, который, кажется, сталкивается с лимитом объектов и приводит к сбою 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 неожиданно завершился».

Очевидно, что 20 тыс. Объектов немного выше, но он падает с гораздо меньшим количеством объектов, если у них есть данные и вложенная сложность.

Быстрый CGI не проблема - я пытался запустить его из командной строки. Я попытался установить для памяти что-то действительно высокое - 6000 МБ и что-то действительно низкое - 24 МБ. Если я установлю его достаточно низким, я получу ошибку «выделенный объем памяти xxx исчерпан».

Я думаю, что это связано с количеством вызываемых функций - своего рода предотвращение вложенности. Я не думал, что вложенность моего ORM была настолько сложной, но, возможно, это так. У меня есть довольно ясные случаи, когда, если я загружаю ОДИН дополнительный объект, он умирает, но загружается менее чем за 3 секунды, если он работает

1 Ответ

4 голосов
/ 06 апреля 2010

Интересно, что в моей среде кажется, что segfault возникает, когда приходит время деконструировать объекты - код, помещенный после того, как цикл работает нормально. Это происходит только тогда, когда PHP начинает отключаться, и происходит сбой.

Вы можете сообщить об ошибке , но вы можете обнаружить, что сопровождающие PHP не сделают все возможное, чтобы поддержать подобные вещи. Я видел, по крайней мере, одно сообщение об ошибке утечки памяти, в которой официальный ответ был по сути «Wontfix: память освобождается после рендеринга страницы, так что это не имеет большого значения», что фактически подразумевает использование вне простого Случай быстрого рендеринга веб-страницы и ее прекращения на самом деле не поддерживается.

После 5 лет полной разработки PHP я пришел к простому правилу: если он ломает PHP, не делайте этого. PHP имеет свои ограничения, и вы окажетесь наиболее успешными, если не будете выходить за эти пределы.

Это означает, что нужно избегать create_function() в PHP <= 5.2 (это приводит к потере памяти как сумасшедшему). Вы можете попробовать использовать <code>create_function() для использования PHP, как если бы это был функциональный язык. Это не так, и вы обнаружите, что он терпит неудачу, если попытаетесь использовать его как таковой.

Так что, если PHP душит вложенные объекты глубиной 40000 уровней ... не вкладывайте объекты глубиной 40000 уровней. Одна из возможных альтернатив - использование массивов вместо объектов, но это звучит довольно отвратительно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...