At 08:39 01.06.2003, Jackson Miller said:
--------------------[snip]--------------------
>Is it possible to reference two instances of an object at once with a
>single variable name while retaining the ability to reference the
>objects seperately?
--------------------[snip]-------------------- 

Not using references.

I once built a small class that handles such stuff. Basically it's a
container for object references that are attached to it, and it will
execute any method to all objects simultaneously. Code plus testbed is
attached below.

The base implementation of CTeeObject checks if that all attached objects
are of the same class of the first attached object, or at least derived
from it. This is how I needed it but it's not mandatory, as the call agent
method or CTeeObject checks each attached object if the method exists. Upon
attaching objects, CTeeObject calls its check_object() method if the object
is ok to attach - you may override this method in a derived class to
perform less or additional checks.

For example you could provide a specialized CTeeObject-derived class that
doesn't use the generic call agent (for performance reasons) but calls
object methods directly (which would be quite feasible in your case). Use
the overridable check_object() to check if the object to attach has a
supported class.

<?php

class CTeeObject {
        var             $arObj;
        var             $class;

        function CTeeObject() {
                // we do nothing in the constructor class
                // use the attach() method
                $this->arObj = array();
        }

        function attach(&$hObj) {
                // if this is the first object, simply accept it.
                // for all successive objects make sure they have
                // the same class (or at least derived from).
                if (!count($this->arObj)) {
                        if (is_object($hObj)) {
                                $this->arObj[] =& $hObj;
                                $this->class = get_class($hObj);
                        }
                }
                else {
                        if (!$this->check_object($hObj))
                                return false;
                        $this->arObj[] =& $hObj;
                }
                return true;
        }

        // override this method in your derived class
        // for additional class checks
        function check_object(&$hObj)
        {
                return is_a($hObj, $this->class);
        }

        // generic call agent
        function call_method($method)
        {
                // accessing unlisted arguments will trigger a notice/warning
                // this is unavoidable here so modify error reporting
                $erep = error_reporting(E_ERROR);

                // build a list of arguments to pass
                $arglist = array();
                for ($i = 1; $i < func_num_args(); ++$i)
                        $arglist[] = func_get_arg($i);

                // build the method call
                $cmd = null;
                for ($i = 0; $i < count($arglist); ++$i)
                        $cmd .= ($cmd ? ',' : null) . "\$arglist[$i]";
                $cmd = "return \$hObj->$method($cmd);";

                // error reporting to standard
                // to have it available in the object implementation
                error_reporting($erep);

                // now walk all attached objects and execute the required
method
                // but check if the object is still an object and that the
method exists
                $result = array();
                for ($i = 0; $i < count($this->arObj); ++$i) {
                        $hObj =& $this->arObj[$i];
                        if (is_object($hObj) && method_exists($hObj, $method))
                                $result[] = eval($cmd);
                        else
                                $result[] = null;
                }
                return $result;
        }
}

////////////////////////////////////////////////////////
// Test Bed

class CBaseTest {
        var     $id;

        function CBaseTest($id)
        {
                $this->id = $id;
        }

        function hello($hellostring)
        {
                echo sprintf('Hello from %s (%s): "%s"<br />',
                                get_class($this), $this->id, $hellostring);
                return $this->id;
        }
}

class CExtendedTest extends CBaseTest {
        
        function say($what, $second)
        {
                echo sprintf('SayWhat from %s (%s): "%s" - %d<br />',
                                get_class($this), $this->id, $what, $second);
                return $this->id;
        }
}

$tee = new CTeeObject;
$tee->attach(new CBaseTest(1));
$tee->attach(new CExtendedTest(1));
$tee->attach(new CBaseTest(2));
$tee->attach(new CExtendedTest(2));
$tee->attach(new CBaseTest(3));
$tee->attach(new CExtendedTest(3));
$tee->attach(new CBaseTest(4));
$tee->attach(new CExtendedTest(4));

echo '<pre>'; $res_hello = $tee->call_method('hello', 'Called hello() (both
base and extended)');
echo '<hr>';  $res_say   = $tee->call_method('say', 'Called say() (only
extended)', 4711);

echo '<hr>';
echo 'Hello results: '; print_r($res_hello);
echo 'Say results: '; print_r($res_say);

?>


-- 
   >O     Ernest E. Vogelsinger
   (\)    ICQ #13394035
    ^     http://www.vogelsinger.at/



-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to