Attempt to assign property of non-object in

During my search for the hierarchical data holy grail I was very helpfully guided to this article ( by another sitepoint user. I’ve studied that in great detail and now have a really thorough understanding of the theory but I’m having a small issue with implementation of the rebuild tree data.

I am getting the error… “Attempt to assign property of non-object in…on line 391

Line 391 is…

$arr[$row->$category_id]->children = array(); 

I suspect this has something to do with version differences between PHP4/5 and object notation and the use of stdClass but it’s just a hunch based on the clues present. I’m guessing the code was written for PHP4.

Here are the relevant functions in their entirety for some context.

         * Fetch the tree data, nesting within each node references to the node's children
         * @return  array       The tree with the node's child data
        function getTreeWithChildren()
            $category_id = $this->fields['id'];
            $parent_id = $this->fields['parent'];
			$this->DB->build( array(	'select' => join(',', $this->getFields()), 
										'from' => $this->table,
										'order' => $this->fields['sort']
							 )		);

            // create a root node to hold child data about first level items
            $root = new stdClass;
            $root->$category_id = 0;
            $root->children = array();
            $arr = array($root);
            // populate the array and create an empty children array
            while ($row = $this->DB->fetch()) {
                $arr[$row->$category_id] = $row;
                $arr[$row->$category_id]->children = array();          
            // now process the array and build the child data
            foreach ($arr as $id => $row) {
                if (isset($row->$parent_id))
                     $arr[$row->$parent_id]->children[$id] = $id;
            return $arr;
         * Rebuilds the tree data and saves it to the database
        function rebuild()
            $data = $this->getTreeWithChildren();
            $n = 0; // need a variable to hold the running n tally
            $level = 0; // need a variable to hold the running level tally
            // invoke the recursive function. Start it processing
            // on the fake "root node" generated in getTreeWithChildren().
            // because this node doesn't really exist in the database, we
            // give it an initial lft value of 0 and an depth of 0.
            $this->_generateTreeData($data, 0, 0, $n);
            // at this point the the root node will have lft of 0, depth of 0
            // and rgt of (tree size * 2 + 1)
            foreach ($data as $id => $row) {
                // skip the root node
                if ($id == 0)
				$this->$db->update( $this->table, array( 'depth' => $row['depth'], 'lft' => $row['lft'], 'rgt' => $row['rgt'] ), $this->fields['id'] . ' = ' . $id );

         * Generate the tree data. A single call to this generates the n-values for
         * 1 node in the tree. This function assigns the passed in n value as the
         * node's lft value. It then processes all the node's children (which
         * in turn recursively processes that node's children and so on), and when
         * it is finally done, it takes the update n-value and assigns it as its
         * rgt value. Because it is passed as a reference, the subsequent changes
         * in subrequests are held over to when control is returned so the rgt
         * can be assigned.
         * @param   array   &$arr   A reference to the data array, since we need to
         *                          be able to update the data in it
         * @param   int     $id     The ID of the current node to process
         * @param   int     $level  The depth to assign to the current node
         * @param   int     &$n     A reference to the running tally for the n-value
        function _generateTreeData(&$arr, $id, $level, &$n)
            $arr[$id]->depth = $level;
            $arr[$id]->lft = $n++;
            // loop over the node's children and process their data
            // before assigning the rgt value
            foreach ($arr[$id]->children as $child_id) {
                $this->_generateTreeData($arr, $child_id, $level + 1, $n);
            $arr[$id]->rgt = $n++;

Can anybody guide me as to how to make this PHP 5 compatible if that is indeed the problem?

Many thanks


Modify $this->DB->fetch() to return an object. Or, type cast the return value to an object. Like
while ($row = (object) $this->DB->fetch())

Thanks I can’t really modify $this->DB->fetch() as it is part of the core framework application I am writing an addon for. I attempted your suggestion of typecasting instead and get a maximum execution time exceeded error.