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 (http://www.phpriot.com/articles/nested-trees-2) 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']
							 )		);
			$this->DB->execute();

 
            // 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)
                    continue;
				
				$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

Andrew

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.