NYCPHP Meetup

NYPHP.org

[nycphp-talk] multiple classes writing to a common container

Dan Cech dcech at phpwerx.net
Fri Mar 19 16:24:03 EST 2004


Another way of achieving this functionality without the need to pass 
references to the classes is to use a static var and call the functions 
as class functions rather than object methods.

This would look like:

class Collector
{
   function addItem ($item)
   {
     Collector::collection($item);
     return TRUE;
   }

   function getCollection ()
   {
     echo "<pre>";
     print_r(Collector::collection ());
     echo "</pre>";
     // return TRUE;
     // return Collector::collection ();
   }

   function collection ($item = NULL)
   {
     static $collection = array ();
     if ( isset ($item) )
     {
       $collection[] = $item;
     }
     return $collection;
   }
}

Now any class can use the collection by calling Collector::addItem () 
and Collector::getCollection ().

This approach means that you never have to worry about whether your 
classes are using the same instance of the collector, and will also 
function correctly as a drop in replacement for the collector class below.

Dan

Chris Hubbard wrote:
> All,
> I've run into an interesting (for me) problem.  And I thought you all 
> might enjoy the solution that I used.
> 
> Here's the scenario:
> I've got multiple classes that are called by a single php file.  I've 
> got a "debug" class that I would like to use to collect debug 
> information that is generated by the multiple classes.   Then if the 
> page is set to debug "on" then the collected debug information from all 
> the classes should be displayed out in one large dump to the screen 
> (either as a separate window aka Smarty), or at the bottom of the 
> screen.  I'd like to have the multiple classes "know" that they are in 
> debug mode vs regular mode.
> I've tried a number of approaches and I have read the manual and 
> tutorials.  I've experimented with static and pass by reference.  I 
> don't think the "extends" structure will work for me, as I will have 
> multiple classes, and there's no inherent relationship between the 
> classes (other than they're being called by the same page).
> 
> I spent a bunch of time spinning around on this, until I changed how I 
> was passing the reference of the collector to the working classes.
> 
> Here's the (working) code:
> <?php
> 
> /**
> * various tests
> */
> 
> class Collector
> {
>    var $collection;
>      function addItem($item)
>    {
>        $this->collection[] = $item;
>        return TRUE;
>    }
>      function getCollection()
>    {
>        echo "<pre>";
>        print_r($this->collection);
>        echo "</pre>";
>        //return TRUE;
>    }
> }
> 
> class testA
> {
>    /*
>    * this class takes three numbers and checks to see
>    * if the first two add up to the last one
>    */
>    var $collection;
>      function testA($a)
>    {
>              /* $a is the reference to the Collector object */
>        $this->collection =& $a;
>    }
>      function test($a, $b, $c)
>    {
>        if ($c == ($a + $b))
>        {
>            echo " testA is true<br>";
>            return TRUE;
>        }else{
>            echo " testA is false<br>";
>            $this->error($a ." + ". $b ." != ". $c);
>            return FALSE;
>        }
>    }
> 
>    function error($text)
>    {
>        /* adds the text to the common collection */
>        $tmp = $this->collection->addItem($text);
>        return TRUE;
>    }
> }
> 
> class testB
> {
>    /*
>    * this class takes three numbers and checks to see
>    * if subtracting the first from the second equals
>    * the last one
>    */
>    var $collection;
> 
>    function testB($a)
>    {
>        /* $a is the reference to the Collector object */
>        $this->collection =& $a;
>    }
> 
>    function test($a, $b, $c)
>    {
>        if ($c == ($a - $b))
>        {
>            echo " testB is true<br>";
>            return TRUE;
>        }else{
>            echo " testB is false<br>";
>            $this->error($a ." - ". $b ." != ". $c);
>            return FALSE;
>        }
>    }
> 
>    function error($text)
>    {
>        /* adds the text to the common collection */
>        $tmp = $this->collection->addItem($text);
>        return TRUE;
>    }
> }
> 
> 
> $coll = new Collector();  // create a new collection
> $testA = new testA(&$coll);  // pass the reference to the common collection
> $testB = new testB(&$coll);  // pass the same collection reference to 
> this class
> 
> /* create an array of test data */
> $tests = array (
> 0 => array(1, 1, 2), 1 => array (1, 2, 3), 2 => array(1, 3, 4),
> 3 => array(1, 3, 2), 4 => array (1, 4, 3), 5 => array(7, 3, 4)
> );
> 
> $count = count($tests);
> 
> $msg = 0;
> 
> /* run through the tests */
> for ($x=0; $x<$count; $x++)
> {
>    if (!$testA->test($tests[$x][0],$tests[$x][1],$tests[$x][2])) // 
> addition test
>    {
>        $msg++;  // if the test fails then increment the flag, so we know 
> to display the collection
>    }
>    if (!$testB->test($tests[$x][0],$tests[$x][1],$tests[$x][2])) // 
> subtraction test
>    {
>        $msg++; // if the test fails then increment the flag, so we know 
> to display the collection
>    }
> }
> 
> if ($msg > 0)
> {
>    echo $coll->getCollection();
> }
> 
> ?>
> 
> This code outputs:
> testA is true
> testB is false
> testA is true
> testB is false
> testA is true
> testB is false
> testA is false
> testB is false
> testA is false
> testB is false
> testA is false
> testB is true
> 
> Array
> (
>    [0] => 1 - 1 != 2
>    [1] => 1 - 2 != 3
>    [2] => 1 - 3 != 4
>    [3] => 1 + 3 != 2
>    [4] => 1 - 3 != 2
>    [5] => 1 + 4 != 3
>    [6] => 1 - 4 != 3
>    [7] => 7 + 3 != 4
> )
> 
> 





More information about the talk mailing list