[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