NYCPHP Meetup

NYPHP.org

[nycphp-talk] Working with recursive "single-referenced" methods and static variables

Dan Cech dcech at phpwerx.net
Tue Feb 24 18:28:57 EST 2004


Phil Powell wrote:

> [CODE]
> class DepartmentTree {
> 
> function &buildTree($id) {
>   static $html;
>   if (!isset($html)) {
>    // DO STUFF HERE TO $html
>   }
>   // DO MORE STUFF
>   if ($condition_is_met) $this->buildTree($newID);
>   $this->html = $html;
>  }
> 
> }
> [/CODE]
> 
> The above (and greatly paraphrased from the 100-line actual class) class 
> and method, in its real form, totally works inasmuch as it successfully 
> always creates an HTML hierarchial tree of departments mapped with child 
> departments.  I have no problem with this.. as long as I only use the 
> class once.
> 
> However, there is a case where I need the entire contents of the 
> departments table dumped out into a resultset, and to do that I figured 
> I would just loop through a query of records that have no parent ID; 
> each id in each row I seed into $tree->buildTree():
> 
> [CODE]
> for ($i = 0; $i < @sizeof($result); $i++) {
> $tree->buildTree($result[$i]->id);
> $this->deptArray += $tree->convert_to_array();
> $tree->clearTreeHTML();
> }
> [/CODE]
> 
> The "convert_to_array()" method will convert the contents of $this->html 
> from HTML content to an array, keeping the original hierarchial order; 
> the "clearTreeHTML()" method will set $this->html to NULL or "".
> 
> Problem is, it does not do that, because apparently "static $html" keeps 
> an instance of it running in the single-referenced instance of 
> "buildTree" method. 
> Based on how best I can explain my problem, and sorry I can't explain it 
> any better w/o dumping the actual code line by line, how have you all 
> figured out the best way to generate multiple, unique instances from a 
> single-referenced method that uses a static local variable?

If you are always going to use $tree as an object, and not call 
DepartmentTree::buildTree (), then just remove the 'static $html;' and 
'$this->html = $html;' lines and replace all instances of '$html' with 
'$this->html'.

This is the normal method for object oriented design, the only reason to 
use static variables is if you are trying to do something tricky like 
the singleton class.

Your code would then be:

class DepartmentTree {

   var $html;

   function &buildTree($id) {
     if (!isset($this->html)) {
      // DO STUFF HERE TO $this->html
     }
     // DO MORE STUFF
     if ($condition_is_met) {
       $this->buildTree($newID);
     }
   }

   function clearTreeHTML () {
     $this->html = NULL;
   }

   function convert_to_array () {
     // PUT YOUR ARRAY CONVERSION HERE
     return (array) $this->html;
   }
}

Which will perform as expected.

Dan




More information about the talk mailing list