phpmysqloodb

PHP - Calling Object in an object


I have a class project creating an OODB with MYSQL and PHP.

Currently I have table filled with the object boxs. I also have a box class which when it is constructed will pull it data from the table and then recursively construct its children in a like manner. That seems to be working well. But I am unable to call a function from a child box.

Here is the class:

class Box1 {
    var $id;
    var $pid;
    var $children;
    var $type;
    var $content;
    var $siblingorder;

    function Box1($bId){

         $q ="SELECT * FROM `box` WHERE id =". $bId;
         $r = mysql_query($q);
         if ($r){
              $row = mysql_fetch_array($r);
              $this->id=$bId;
              $this->pid=$row[1];
              $this->children=$row[2];
              $this->type=$row[3];
              $this->siblingorder=$row[5];
              $this->content=$row[6];
              //echo $this->id."<br />";
              if(isset($this->children)){
                 //echo $this->children."<br />";
                 $kids = explode(',', $this->children);
                 foreach ($kids as $key => $value) {
                     $varname = "box".$value;
                     //global $$varname;
                     //echo $varname."<br>";
                     $$varname = new Box1($value);
                 }
             }
         }
    }//constructor

    function display(){
         echo "<div style='border: solid 2px;'>";
         echo $this->id;
         echo "<br />";
         if(isset($this->children)){
            $kids = explode(',', $this->children);
        foreach ($kids as $key => $value) {
                $varname = "box".$value;
                //echo $varname."<br />";
                $$varname->display();
        }
         }
         echo "</div>";
    }//End DISPLAY

    function update(){

    }//End UPDATE

}

Here is the code calling the constructor and the display function which in turn should call the children boxes display function:

    $box1 = new Box1(1);
    $box1->display();

Any help or insight would be much appreciated.


Solution

  • As stated in the first comment, the problem is because $$varname is created and assigned inside the constructor. But it does not exist in the function display. Once the contructor has been called, these variables do not exist anymore. Find some code below that shows you how to make children an array of objects of type Box1

    class Box1 {
    
        var $id;
        var $pid;
        var $children;
        var $type;
        var $content;
        var $siblingorder;
    
        function Box1($bId){
    
             $q ="SELECT * FROM `box` WHERE id =". $bId;
             $r = mysql_query($q);
             if ($r){
                  $row = mysql_fetch_array($r);
                  $this->id=$bId;
                  $this->pid=$row[1];
                  $this->children = array();//[*]
                  $this->type=$row[3];
                  $this->siblingorder=$row[5];
                  $this->content=$row[6];
    
                  //now we fill this->children with objects of type Box1
                  if ($row[2] != '') {
                      $kids = explode(',', $row[2]);
                      foreach ($kids as $value) {
                          $this->children[] = new Box1($value);
                      }
                  }
             }
        }//constructor
    
        function display(){
             echo "<div style='border: solid 2px;'>";
             echo $this->id;
             echo "<br />";
             foreach ($this->chidren as $kid) {
                    $kid->display();
             }
             echo "</div>";
        }//End DISPLAY
    
        function update(){
    
        }//End UPDATE
    
    }
    

    [*] : Here we decide that children is always an array of Box1. Of course this array can be empty if there are no children. It's a matter of taste, some people would rather let it to null if no children. But in this case, you would have to check for null value before you iterate over $this->children in display().