J.K.A.
J.K.A.

Reputation: 7404

Fatal error in CodeIgniter while calling function itselft

I want to insert dynamic data into my preorder traversal table. I am using rebuild_tree technique by referencing this tutorial : http://www.sitepoint.com/hierarchical-data-database-3/

Here I modified the code as per the need in codeigniter. But when I calling function rebuild_tree in foreach loop it showing the fatal error like :

Fatal error: Maximum function nesting level of '100' reached, aborting! in /var/www/hr/system/database/drivers/mysql/mysql_driver.php on line 199 Call Stack: 0.0389 360600 1. {main}() /var/www/hr/index.php:0 0.0401 468096 2. require_once('/var/www/hr/system/core/CodeIgniter.php') /var/www/hr/index.php:240 0.0689 3798516 3. call_user_func_array() /var/www/hr/system/core/CodeIgniter.php:359 0.0689 3798588 4. Structure->add_structure() /var/www/hr/system/core/CodeIgniter.php:0 0.0689 3798632 5. 
structure_model->rebuild_tree() /var/www/hr/application/controllers/test/structure.php:42 0.0701 3928356 6. structure_model->rebuild_tree() /var/www/hr/application/models/test/structure_model.php:35 0.0703 3931572 7. structure_model->rebuild_tree() /var/www/hr/application/models/test/structure_model.php:35 0.0705 3934788 8. structure_model->rebuild_tree() /var/www/hr/application/models/test/structure_model.php:35 0.0706 3938008 9. 
    CI_DB_driver->query() /var/www/hr/application/models/xome/structure_model.php:29 0.0848 4216988 97. CI_DB_driver->simple_query() /var/www/hr/system/database/DB_driver.php:299 0.0848 4216988 98. CI_DB_mysql_driver->_execute() /var/www/hr/system/database/DB_driver.php:453 0.0848 4216988 99. CI_DB_mysql_driver->_prep_query() /var/www/hr/system/database/drivers/mysql/mysql_driver.php:178 

And Following is my code:

function rebuild_tree($parent, $left) {
        $resultArr = array();
        $parent = $_GET['level'];
        $left = $_GET['lft'];
        $right = $_GET['rgt'];

        $right = $left + 1;
        $sql = 'SELECT * FROM subunit WHERE level="' . $parent . '";';
        $query = $this->db->query($sql);
        $data = $query->result();

        foreach ($data as $datap) {
            $resultArr['name'] = $datap->name;
            $resultArr['level'] = $datap->level;
            $right = $this->rebuild_tree($resultArr['level'], $right);
        }

        $sql = 'UPDATE subunit SET lft=' . $left . ', rgt=' . $right . ' WHERE name="' . $parent . '";';
        $query = $this->db->query($sql);
        return $right + 1;
    }

Is there any solution for this. Thank you.

Upvotes: 0

Views: 593

Answers (1)

Robin Castlin
Robin Castlin

Reputation: 10996

Be careful when calling the function itself. Often it might end up calling itself forever. You need some kind of limitation.

You can check most of Codeigniters own libraries, and check the initialize(). That's a good example on how to handle a function which calls itself. Basicly it calls itself till no array remains, thus having an end.

In your case if 2 mysql rows are each other's parents or any similiar, you've opened the door for infinite loops.

Solution

The real problem in your function is that you pass an argument which is supposed to get a new value, however you override that value through your $_GET. That means that the 2nd function calls does exactly the same as the first function call, the third the same, the fourth the same and so on. Since the function calls never changes AND calls itself, your problem occur.

Change above part to:

$parent = $this->input->get('level');
$left = ($left ?: $this->input->get('lft'));
$right = $this->input->get('rgt');

Upvotes: 1

Related Questions