This sounds like a matter that ought to make it to the programmers who code
PHP itself.  In the meantime can you code around it now that you know the
bug is there?

Mike


"Marco Tabini" <[EMAIL PROTECTED]> wrote in message
news:1036725595.21741.868.camel@;localhost.localdomain...
> I'm not sure if my answer is going to be of much help, but I think this
> has to do with the way PHP handles references and copies of objects--it
> uses what I understand is a lazy copy mechanism, and thus the results on
> object manipulations can yield odd results. There was a discussion on a
> similar problem on PHP-DEV a while back--if you search the forums you
> should be able to find it.
>
> Hope this helps...
>
>
> Marco
> -------------
> php|architect -- The Monthly Magazine For PHP Professionals
> Come visit us on the web at http://www.phparch.com!
>
> On Thu, 2002-11-07 at 21:36, Tim Molendijk wrote:
> > First of all I would like to say that I know this is a lot of text but I
> > would be very pleased if you take a little time to read it nevertheless.
The
> > situation described below is not complicated at all...
> > =====================================
> >
> > Hello all,
> >
> > I'm dealing with this really weird problem which occurs when dealing
with
> > references within objects pointing to other objects. I'm trying to find
out
> > what it is now for a few days and I still don't get it. I minimised the
code
> > around the problem and it's weirder than ever. I would really appreciate
it
> > when you could take a look... I'm pretty experienced at PHP but perhaps
you
> > know something that I don't know.
> >
> > We have two different classes: Container and Child. Container objects
> > contain a Child object in its $child property. A Child object has a
$parent
> > property, which contains a *reference* to the Container object by which
it
> > is held.
> > So $containerObject should be the *same* as
$containerObject->child->parent.
> > To test this Container objects have a $property property. When changing
this
> > property the difference between one object and identical/cloned objects
> > becomes visible.
> >
> > Now take a look at the following code. The indented text is code, the
rest
> > are comments. The code for the class Container and class Child are also
> > included. Please scroll down or take a look at the attached file.
> >
> > begin first code snippet --------------------------------
> >                 <?php
> >
> > /* New Container object created. At the same time it sets a Child object
in
> > its $child attribute. (This is indicated by passing TRUE.) */
> >                 $testContainer1 = new Container(TRUE);
> > /* The Container object is created, the Child object is set and its
> > reference to the Container object is set. Now it prints
> > $testContainer1->property and $testContainer->child->parent->property.
These
> > should have an identical value because they should be from the same
object
> > (not cloned/identical, but the same).
> > This is the result:
> > property = 'state 1'
> > child->parent->property = 'state 1'
> > So this is as expected, no problem... yet. */
> >                 $testContainer1->printState();
> >
> > /* Now $testContainer1's $property property is changed into another
value.
> > /*
> >                 $testContainer1->property = 'state 2';
> > /* Now $testContainer1->child->parent->property should also have value
> > 'state 2', but it HAS NOT!
> > This is the result:
> > property = 'state 2'
> > child->parent->property = 'state 1'
> > Obviously $testContainer1->child->parent->property is not the same
object as
> > $testContainer1, but a clone! */
> >                 $testContainer1->printState();
> >
> >                 ?>
> > end first code snippet --------------------------------
> >
> > Well, this is the whole problem... Why on earth isn't it a reference,
while
> > I really did assign it as a reference in the code (see class code).
> >
> > Now to make the whole thing even weirder, take a short look at the
following
> > code. It is almost completely the same as above, except that instead of
> > giving the Container constructor the command to assign a Child object to
the
> > $child property, this command is given manually by calling method
load() --
> > which is the method that Container constructor uses to load the Child
> > object.
> >
> > begin second code snippet --------------------------------
> >                 <?php
> >
> > /* Here the Container object is created again. But now no TRUE is passed
> > because we don't want the Container constructor method to create and
assign
> > a Child object to the $child property. */
> >                 $testContainer2 = new Container;
> > /* In the first code snippet load() is called from the Container
constructor
> > method. So in fact nothing has changed, except the fact that load() is
> > called from the client scope instead of the Container object scope now.
*/
> >                 $testContainer2->load();
> >                 $testContainer2->printState();
> >
> >                 $testContainer2->property = 'state 2';
> > /* After $property has been modified again, $testContainer2's state is
> > printed again, and now the result is DIFFERENT!!!:
> > property = 'loaded state 2'
> > child->parent->property = 'loaded state 2'
> > This is the CORRECT result!!! This is what we also expected from the
first
> > code snippet!!! And this while the executed codes are in fact
identical!!!
> > How on earth is this possible?!? */
> >                 $testContainer2->printState();
> >
> >                 ?>
> > end second code snippet --------------------------------
> >
> > Well, this is the contradiction I wanted to show you all. I don't see
the
> > logics of it all, but ofcourse I could be missing one obvious thing...
> > actually I hope so, because I need the construction as in the first code
> > snippet.
> >
> > Below the code for the classes Container en Child.
> >
> > begin third code snippet --------------------------------
> > <?php
> >
> > class Container
> > {
> >
> >     var $children;
> >     var $property;
> >
> >     function Container($load = FALSE)
> >     {
> >         $this->property = 'not loaded';
> >         if ($load) {
> >             $this->load();
> >         }
> >     }
> >
> >     function load()
> >     {
> >         $newChild = new Child(1);
> >         $this->add(&$newChild);
> >         $this->property = 'state 1';
> >     }
> >
> >     function add($child)
> >     {
> > /* Here a reference of $this (the Container object) is assigned to
$child's
> > $parent attribute. */
> >         $child->parent = &$this;
> > /* Here $child (the newly created Child object) is assigned to the
> > container's $child property. */
> >         $this->child = &$child;
> >     }
> >
> >     function printState()
> >     {
> >         print 'property = \'' . $this->property . '\'<BR>' .
> >             'child->parent->property = \'' .
$this->child->parent->property
> > . '\'<P>';
> >     }
> >
> > }
> >
> > class Child
> > {
> >
> >     var $id;
> >     var $parent;
> >
> >     function Child($id)
> >     {
> >         $this->id = $id;
> >     }
> >
> > }
> >
> > ?>
> > end third code snippet --------------------------------
> >
> > Well that's it. I hope someone can help me on this. I'm not a person who
> > asks for help very quick. I prefer finding it out myself, also because
I'm
> > pretty experienced at PHP. But this is the first time I really can't
figure
> > out what it is... I really NEEEEED you now :)
> >
> > Good luck and a lot of thanks in advance,
> >
> > Tim.
> >
> > P.S. I'm using PHP4, I do not know this code's reliability and behaviour
> > when running it with previous versions.
> >
> >
> > begin 666 complex.php
> > M/#]P:' -"@T*8VQA<W,@0V]N=&%I;F5R#0I[#0H)#0H)=F%R("1C:&EL9')E
> > M;CL-"@EV87(@)'!R;W!E<G1Y.PT*#0H)9G5N8W1I;VX@0V]N=&%I;F5R*"1L
> > M;V%D(#T@1D%,4T4I#0H)>PT*(" @(" @(" D=&AI<RT^<')O<&5R='D@/2 G
> > M;F]T(&QO861E9"<[#0H)(" @(&EF("@D;&]A9"D@>PT*(" @( D))'1H:7,M
> > M/FQO860H*3L-"B @(" @(" @?0T*"7T-"@T*(" @(&9U;F-T:6]N(&QO860H
> > M*0T*(" @('L-"B @(" @(" @)&YE=T-H:6QD(#T@;F5W($-H:6QD*#$I.PT*
> > M(" @(" @(" D=&AI<RT^861D*"1N97=#:&EL9"D[#0H@(" @(" @("1T:&ES
> > M+3YP<F]P97)T>2 ]("=S=&%T92 Q)SL-"B @("!]#0H-"@EF=6YC=&EO;B!A
> > M9&0H)&-H:6QD*0T*"7L-"@D))&-H:6QD+3YP87)E;G0@/2 F)'1H:7,[#0H)
> > M"21T:&ES+3YC:&EL9" ]("8D8VAI;&0[#0H)?0T*#0H@(" @9G5N8W1I;VX@
> > M<')I;G13=&%T92@I#0H@(" @>PT*(" @(" @("!P<FEN=" G<')O<&5R='D@
> > M/2!<)R<@+B D=&AI<RT^<')O<&5R='D@+B G7"<\0E(^)R N#0H@(" @(" @
> > M(" @(" G8VAI;&0M/G!A<F5N="T^<')O<&5R='D@/2!<)R<@+B D=&AI<RT^
> > M8VAI;&0M/G!A<F5N="T^<')O<&5R='D@+B G7"<\4#XG.PT*(" @('T-"@D-
> > M"GT-"@T*8VQA<W,@0VAI;&0-"GL-"@D-"@EV87(@)&ED.PT*"79A<B D<&%R
> > M96YT.PT*"0T*"69U;F-T:6]N($-H:6QD*"1I9"D-"@E[#0H)"21T:&ES+3YI
> > M9" ]("1I9#L-"@E]#0H)#0I]#0H-"@T*)'1E<W1#;VYT86EN97(R(#T@;F5W
> > M($-O;G1A:6YE<BA44E5%*3L-"B1T97-T0V]N=&%I;F5R,BT^<')I;G13=&%T
> > [EMAIL PROTECTED]*#0HD=&5S=$-O;G1A:6YE<C(M/G!R;W!E<G1Y(#T@)W-T871E(#(G
> > M.PT*)'1E<W1#;VYT86EN97(R+3YP<FEN=%-T871E*"D[#0H-"G!R:6YT("<\
> > M2%(^)SL-"@T*)'1E<W1#;VYT86EN97(Q(#T@;F5W($-O;G1A:6YE<CL-"B1T
> > M97-T0V]N=&%I;F5R,2T^;&]A9"@I.PT*)'1E<W1#;VYT86EN97(Q+3YP<FEN
> > M=%-T871E*"D[#0H-"B1T97-T0V]N=&%I;F5R,2T^<')O<&5R='D@/2 G<W1A
> > M=&4@,B<[#0HD=&5S=$-O;G1A:6YE<C$M/G!R:6YT4W1A=&4H*3L-"@T*/SX-
> > !"@``
> > `
> > end
> >
> >
> > --
> > PHP General Mailing List (http://www.php.net/)
> > To unsubscribe, visit: http://www.php.net/unsub.php
> >
>
>



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

Reply via email to