Hi,

Friday, November 8, 2002, 12:36:03 PM, you wrote:
TM> First of all I would like to say that I know this is a lot of text but I
TM> would be very pleased if you take a little time to read it nevertheless. The
TM> situation described below is not complicated at all...
TM> =====================================

TM> Hello all,

TM> I'm dealing with this really weird problem which occurs when dealing with
TM> references within objects pointing to other objects. I'm trying to find out
TM> what it is now for a few days and I still don't get it. I minimised the code
TM> around the problem and it's weirder than ever. I would really appreciate it
TM> when you could take a look... I'm pretty experienced at PHP but perhaps you
TM> know something that I don't know.

TM> We have two different classes: Container and Child. Container objects
TM> contain a Child object in its $child property. A Child object has a $parent
TM> property, which contains a *reference* to the Container object by which it
TM> is held.
TM> So $containerObject should be the *same* as $containerObject->child->parent.
TM> To test this Container objects have a $property property. When changing this
TM> property the difference between one object and identical/cloned objects
TM> becomes visible.

TM> Now take a look at the following code. The indented text is code, the rest
TM> are comments. The code for the class Container and class Child are also
TM> included. Please scroll down or take a look at the attached file.

TM> begin first code snippet --------------------------------
TM>                 <?php

TM> /* New Container object created. At the same time it sets a Child object in
TM> its $child attribute. (This is indicated by passing TRUE.) */
TM>                 $testContainer1 = new Container(TRUE);
TM> /* The Container object is created, the Child object is set and its
TM> reference to the Container object is set. Now it prints
$testContainer1->>property and $testContainer->child->parent->property. These
TM> should have an identical value because they should be from the same object
TM> (not cloned/identical, but the same).
TM> This is the result:
TM> property = 'state 1'
child->>parent->property = 'state 1'
TM> So this is as expected, no problem... yet. */
TM>                 $testContainer1->printState();

TM> /* Now $testContainer1's $property property is changed into another value.
TM> /*
TM>                 $testContainer1->property = 'state 2';
TM> /* Now $testContainer1->child->parent->property should also have value
TM> 'state 2', but it HAS NOT!
TM> This is the result:
TM> property = 'state 2'
child->>parent->property = 'state 1'
TM> Obviously $testContainer1->child->parent->property is not the same object as
TM> $testContainer1, but a clone! */
TM>                 $testContainer1->printState();

TM>                 ?>
TM> end first code snippet --------------------------------

TM> Well, this is the whole problem... Why on earth isn't it a reference, while
TM> I really did assign it as a reference in the code (see class code).

TM> Now to make the whole thing even weirder, take a short look at the following
TM> code. It is almost completely the same as above, except that instead of
TM> giving the Container constructor the command to assign a Child object to the
TM> $child property, this command is given manually by calling method load() --
TM> which is the method that Container constructor uses to load the Child
TM> object.

TM> begin second code snippet --------------------------------
TM>                 <?php

TM> /* Here the Container object is created again. But now no TRUE is passed
TM> because we don't want the Container constructor method to create and assign
TM> a Child object to the $child property. */
TM>                 $testContainer2 = new Container;
TM> /* In the first code snippet load() is called from the Container constructor
TM> method. So in fact nothing has changed, except the fact that load() is
TM> called from the client scope instead of the Container object scope now. */
TM>                 $testContainer2->load();
TM>                 $testContainer2->printState();

TM>                 $testContainer2->property = 'state 2';
TM> /* After $property has been modified again, $testContainer2's state is
TM> printed again, and now the result is DIFFERENT!!!:
TM> property = 'loaded state 2'
child->>parent->property = 'loaded state 2'
TM> This is the CORRECT result!!! This is what we also expected from the first
TM> code snippet!!! And this while the executed codes are in fact identical!!!
TM> How on earth is this possible?!? */
TM>                 $testContainer2->printState();

TM>                 ?>
TM> end second code snippet --------------------------------

TM> Well, this is the contradiction I wanted to show you all. I don't see the
TM> logics of it all, but ofcourse I could be missing one obvious thing...
TM> actually I hope so, because I need the construction as in the first code
TM> snippet.

TM> Below the code for the classes Container en Child.

TM> begin third code snippet --------------------------------
TM> <?php

TM> class Container
TM> {

TM>     var $children;
TM>     var $property;

TM>     function Container($load = FALSE)
TM>     {
TM>         $this->property = 'not loaded';
TM>         if ($load) {
TM>             $this->load();
TM>         }
TM>     }

TM>     function load()
TM>     {
TM>         $newChild = new Child(1);
TM>         $this->add(&$newChild);
TM>         $this->property = 'state 1';
TM>     }

TM>     function add($child)
TM>     {
TM> /* Here a reference of $this (the Container object) is assigned to $child's
TM> $parent attribute. */
TM>         $child->parent = &$this;
TM> /* Here $child (the newly created Child object) is assigned to the
TM> container's $child property. */
TM>         $this->child = &$child;
TM>     }

TM>     function printState()
TM>     {
TM>         print 'property = \'' . $this->property . '\'<BR>' .
TM>             'child->parent->property = \'' . $this->child->parent->property
TM> . '\'<P>';
TM>     }

TM> }

TM> class Child
TM> {

TM>     var $id;
TM>     var $parent;

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

TM> }

?>>
TM> end third code snippet --------------------------------

TM> Well that's it. I hope someone can help me on this. I'm not a person who
TM> asks for help very quick. I prefer finding it out myself, also because I'm
TM> pretty experienced at PHP. But this is the first time I really can't figure
TM> out what it is... I really NEEEEED you now :)

TM> Good luck and a lot of thanks in advance,

TM> Tim.

TM> P.S. I'm using PHP4, I do not know this code's reliability and behaviour
TM> when running it with previous versions.

Try this for your load() function:


function load()
    {
        $newChild =& new Child(1);
        $this->add(&$newChild);
        $this->property = 'state 1';
    }

-- 
regards,
Tom


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

Reply via email to