Demiro-FE-Architect
Demiro-FE-Architect

Reputation: 3740

Simple PHP recursion - why am I getting out of memory?

So I am having a problem with memory out message...

I have a class (controller) with index method...something like this:

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

where $this->CATS is an array fetched from DB with around only 3000 rows...

each row looks something like this

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
)

So not a big deal...and I've set php_ini to use 128M ... and I am getting:

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 35 bytes) in D:\root\app\my.controller.php on line 186

my goal is to get the list of parent cats that will have another firled called is_set of boolean type... the is_set value is TRUE when ALL of the children (and self) have trader_category_id set to other than 0...

so that's why I need to get all of the children for each parent cat...

CAN it be done in db query (mysql) alone?

Upvotes: 1

Views: 529

Answers (2)

Rolando Cruz
Rolando Cruz

Reputation: 2784

You forgot to specify under what conditions should the function stop and return.

EDIT

You have an error in your code logic it seems:

Lets say the first member of the array $this->CATS that was placed in $CAT is this:

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

The very first call to __set_all_sub_cats($CAT["id"]) will have 1 as the id and 0 as the parent. $this refers to the original object (I assume this is the one with id equal to 0).

Then __set_all_sub_cats() has a line like this:

foreach($this->CATS as $C)

So basically you are going over the $this->CATS array once again. But you never created another instance of your class. You are still using the original object

EDIT

The other answer explains it better

Upvotes: 2

Explosion Pills
Explosion Pills

Reputation: 191749

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

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

Problem seems to be there. $CAT is still in $this->CATS (you never actually remove it) so you end up trying to set the sub categories for the same category constantly.

Upvotes: 0

Related Questions