> -----Original Message-----
> From: Daniel Kolbo [mailto:kolb0...@umn.edu]
> Sent: 11 July 2010 23:19
> 
> Hello PHPers,
> 
> I'm having some trouble understanding some PHP behaviour.  The
> following
> example script exhibits the behaviour which I cannot understand.

I'm pretty sure that this is *not* a bug. I'll answer your last
question first, and then demonstrate with your code.

> I'm nervous to use "self::$a = $this;" because I don't want to be
> copying the whole object.  However, isn't $this just a reference to
> the
> object, so "self::$a = $this;" is just copying the reference and not
> the
> actual object, right?

Not exactly, although everybody seems to refer to it as a reference
for convenience. Most of the time it doesn't matter, but when you
start introducing references to objects it can - it's better to think
of an object variable as holding the object's *handle*
(see http://php.net/anguage.oop5.references.php for more on this), so
it's clear exactly what a reference is referencing.

Now for your code:

> [code]
> <?php
> 
> class A
> {
>       public static $a = 3;
> 
>       function __construct()
>       {
>               //self::$a = $this; //[i]
>               self::$a =& $this; //[ii]
>       }
> }
> 
> class B extends  A
> {
>       function __construct()
>       {
>               parent::__construct();
>       }
> }
> 
> class C {
>       var $c;
> 
>       function __construct()
>       {
>               $this->c =& A::$a;
>       }
> 
> }
> 
> 
> $c = new C;

[i] & [ii]  in C::__construct(): $c->c = reference to same value as
            A::$a (currently (int)3)
            NOTE: because of how references work, A::$a is now also a
            reference to (int)3.

> $b = new B;

[i]  in A::__construct(): A::$a = handle of object B(1) (also assigned to
     global $b)
     NOTE: $c->c, as reference to $A::a, now also references handle of
           object B(1)

[ii] in A::__construct(): A::$a = reference to handle of object B(1)
     NOTE: since we are assigning a new reference to a variable which is
           already a reference, ONLY this reference changes -- so $c->c
           is still a reference to (int)3...!

> $cee = new C;

Irrelevant -- the damage has already been done!

> var_dump($c->c); // [i] prints object(B), but [ii] prints int 3
> var_dump($cee->c); // [i] prints object(B), and [ii] prints
> object(B)

... which is correct according to my interpretation.

This has been such a regular confusion, that some time ago I wrote
this test script:

<?php

        class test {

                public $me;
        }

        $t = new test;
        $t->me = 'Original';

        $copy_t = $t;
        $ref_t = &$t;

        $copy_t = new test;
        $copy_t->me = 'Altered Copy';

        echo <<<RESULT1
        Original: $t->me<br />
        Copy: $copy_t->me<br />
        Reference: $ref_t->me<br />
RESULT1;

        $ref_t = new test;
        $ref_t->me = 'Altered Reference';

        echo <<<RESULT2
        <br />
        Original: $t->me<br />
        Copy: $copy_t->me<br />
        Reference: $ref_t->me<br />
RESULT2;


        $s = 'String';

        $copy_s = $s;
        $ref_s = &$s;

        $copy_s = 'String Copy';

        echo <<<RESULT3
        <br />
        Original: $s<br />
        Copy: $copy_s<br />
        Reference: $ref_s<br />
RESULT3;

        $ref_s = 'String Reference';

        echo <<<RESULT4
        <br />
        Original: $s<br />
        Copy: $copy_s<br />
        Reference: $ref_s<br />
RESULT4;

?>

Which gives this output:

        Original: Original
        Copy: Altered Copy
        Reference: Original

        Original: Altered Reference
        Copy: Altered Copy
        Reference: Altered Reference

        Original: String
        Copy: String Copy
        Reference: String

        Original: String Reference
        Copy: String Copy
        Reference: String Reference

Which demonstrates how exactly the behaviour of objects correlates to
scalars with regards to copying and referencing -- but may not be
exactly what you expect if you think of object variables as always
holding a reference to the object. I would heartily recommend always
to think of an object variable as holding the object's *handle*, and
*not* a reference - this may croggle your brain a bit, but makes it a
Lot clearer what's happening in edge cases like this.

Cheers!

Mike

 -- 
Mike Ford,
Electronic Information Developer, Libraries and Learning Innovation,  
Leeds Metropolitan University, C507, Civic Quarter Campus, 
Woodhouse Lane, LEEDS,  LS1 3HE,  United Kingdom 
Email: m.f...@leedsmet.ac.uk 
Tel: +44 113 812 4730





To view the terms under which this email is distributed, please go to 
http://disclaimer.leedsmet.ac.uk/email.htm

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

Reply via email to