Простая рекурсия PHP - почему мне не хватает памяти? - PullRequest
1 голос
/ 09 сентября 2011

Итак, у меня проблема с сообщением об отсутствии памяти ...

У меня есть класс (контроллер) с методом индекса ... примерно так:

function index($parent=0){
    $this->__set_all_cats();
    foreach($this->CATS as $CAT){
        ...

        if($CAT["parent_id"] == $parent) $this->__set_all_sub_cats($CAT["id"]);
        ...
    }
}  



function __set_all_cats(){
    $CATS = ...get array from db
    foreach($CATS as $CAT){
        $this->CATS[$CAT["id"]] = $CAT;
    }
}

function __set_all_sub_cats($cat_id, $start = 1){
    if($start) $this->subs=array();
    $this->subs[] = $cat_id;

    $CAT = $this->CATS[$cat_id];
    $parent = $CAT["parent_id"];

    foreach($this->CATS as $C){
        if($C["parent_id"] == $parent){
            $this->__set_all_sub_cats($C["id"], 0);
        }
    }
}

где $this-> CATS - это массив, извлеченный из БД, содержащий всего около 3000 строк ...

каждая строка выглядит примерно так

Array(
   [id] => 18674
   [importer_id] => 6
   [parent_id] => 0
   [category_id] => 1
   [category_name] => Category name
   [category_slug] => category0slug
   [private_category_id] => 0
   [trader_category_id] => 951
)

Так что ничего страшного ... и яя установил php_ini для использования 128M ... и я получаю:

Неустранимая ошибка : допустимый объем памяти 134217728 байт исчерпан (попытался выделить 35 байт) в D: \ root \ app \ my.controller.php в строке 186

Моя цель состоит в том, чтобы получить список родительских кошек, у которых будет еще один обработанный файл с именем is_set логического типа ... значение is_set равно TRUE, когда для ВСЕХ детей (и self) trader_category_id установлено значениекроме 0 ...

, поэтому мне нужно получить все дочерние элементы для каждого родительского кота ...

МОЖЕТ ли это быть сделано в одном запросе БД (mysql)

Ответы [ 2 ]

2 голосов
/ 09 сентября 2011

Вы забыли указать, при каких условиях функция должна останавливаться и возвращаться.

РЕДАКТИРОВАТЬ

В вашей логике кода вы видите ошибку:

Допустим, первый член массива $this->CATS, который был помещен в $CAT, выглядит так:

Array(
      [id] => 1
      [parent_id] => 0
      ...
     )

Самый первый вызов __set_all_sub_cats($CAT["id"]) будет иметь 1 в качестве id и 0 в качестве родителя.$this относится к исходному объекту (я предполагаю, что это объект с id, равным 0).

Тогда __set_all_sub_cats() имеет такую ​​строку:

foreach($this->CATS as $C)

В общем, вы снова просматриваете массив $this->CATS.Но вы никогда не создавали другой экземпляр вашего класса.Вы все еще используете исходный объект

РЕДАКТИРОВАТЬ

Другой ответ объясняет это лучше

0 голосов
/ 09 сентября 2011
$CAT = $this->CATS[$cat_id];
$parent = $CAT["parent_id"];

foreach($this->CATS as $C){
    if($C["parent_id"] == $parent){

Проблема, похоже, есть.$CAT все еще находится в $this->CATS (вы его никогда не удаляете), поэтому вы пытаетесь постоянно устанавливать подкатегории для одной и той же категории.

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