RE: [PHP] Static Class Member References
-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-mebr / Copy: $copy_t-mebr / Reference: $ref_t-mebr / RESULT1; $ref_t = new test; $ref_t-me = 'Altered Reference'; echo RESULT2 br / Original: $t-mebr / Copy: $copy_t-mebr / Reference: $ref_t-mebr / RESULT2; $s = 'String'; $copy_s = $s; $ref_s = $s; $copy_s = 'String Copy'; echo RESULT3 br / Original: $sbr / Copy: $copy_sbr / Reference: $ref_sbr / RESULT3; $ref_s = 'String Reference'; echo RESULT4 br / Original: $sbr / Copy: $copy_sbr / Reference: $ref_sbr / 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
Re: [PHP] Static Class Member References
Ah, so assigning a reference to a variable already holding a reference changes that variable's reference only in the same way that unsetting a reference doesn't unset the other variables referencing the same thing, yes? $a = 5; $b = $a; print $a; 5 unset($b); // does not affect $a print $a; 5 // and according to Mike's previous message $b = $a; $c = 10; $b = $c; // does not affect $a print $a 5 That makes a lot of sense. If it didn't work this way there would be no easy way to untangle references. In the case of foreach($array as $key = $value) { ... } the first value in the array would continuously be overwritten by the next value. 1. $value gets reference to first array value 2. on each step through the loop, the first array value would be overwritten by the next value in the loop since $value is forever tied to it by the initial reference assignment. That would be a Bad Thing (tm). Thanks for the clarification, Mike. David
Re: [PHP] Static Class Member References
David Harkness wrote: Ah, so assigning a reference to a variable already holding a reference changes that variable's reference only in the same way that unsetting a reference doesn't unset the other variables referencing the same thing, yes? $a = 5; $b = $a; print $a; 5 unset($b); // does not affect $a print $a; 5 // and according to Mike's previous message $b = $a; $c = 10; $b = $c; // does not affect $a print $a 5 That makes a lot of sense. If it didn't work this way there would be no easy way to untangle references. In the case of foreach($array as $key = $value) { ... } the first value in the array would continuously be overwritten by the next value. 1. $value gets reference to first array value 2. on each step through the loop, the first array value would be overwritten by the next value in the loop since $value is forever tied to it by the initial reference assignment. That would be a Bad Thing (tm). Thanks for the clarification, Mike. David The big aha moment for was when realizing that when assigning a reference to a variable you only change its reference and not any other variable that may also have shared the same reference. Yuck that's a mouth full. This happened when Mike said, NOTE: since we are assigning a new reference to a variable which is already a reference, ONLY this reference changes. Yes, i agree with you David (on both of your points). Thanks for the example using the unset. This further clarified/solidified my understanding. Now, with this new understanding, I also wish to comment that if i assign (without reference) $this, i don't have to be too worried about bloating the memory, b/c i'm only assigning/copying the identifer or *handle* and not the actual object itself. In case, someone reads this in the archive the link is: http://php.net/manual/en/language.oop5.references.php Mike, thank you a ton. Regards. ` -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Static Class Member References
On 12 July 2010 22:54, Daniel Kolbo kolb0...@umn.edu wrote: Richard Quadling wrote: On 11 July 2010 23:19, Daniel Kolbo kolb0...@umn.edu wrote: Hello PHPers, I'm having some trouble understanding some PHP behaviour. The following example script exhibits the behaviour which I cannot understand. [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; $b = new B; $cee = new C; 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) ? [/code] Why does $c-c print 'int 3' ? 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? Thanks in advance What do you think the value should be? A static property is bound to the class and not to an instance of the class. So, A::$a is a reference to the static value. If you alter the value, it will be altered for a subclasses of A and for any other reference to it. I think var_dump($c-c); would print object(B), but it's printing int 3. The reference is *not* being updated. I think this is a bug. What do you think? Thanks ` What version of PHP are you using? -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Static Class Member References
On 13 July 2010 09:46, Richard Quadling rquadl...@gmail.com wrote: On 12 July 2010 22:54, Daniel Kolbo kolb0...@umn.edu wrote: Richard Quadling wrote: On 11 July 2010 23:19, Daniel Kolbo kolb0...@umn.edu wrote: Hello PHPers, I'm having some trouble understanding some PHP behaviour. The following example script exhibits the behaviour which I cannot understand. [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; $b = new B; $cee = new C; 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) ? [/code] Why does $c-c print 'int 3' ? 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? Thanks in advance What do you think the value should be? A static property is bound to the class and not to an instance of the class. So, A::$a is a reference to the static value. If you alter the value, it will be altered for a subclasses of A and for any other reference to it. I think var_dump($c-c); would print object(B), but it's printing int 3. The reference is *not* being updated. I think this is a bug. What do you think? Thanks Aha! $c = new C; At this stage $c-c will be a reference to the static A::$a = 3. $b = new B; Now, as B's constructor calls A's constructor which replaces the static A::$a with a reference to the instance $b, the static A::$a should now be $b $cee = new C; At this stage $cee-c will be a reference to the static A::$a = $b. But, when var_dump()'d, $c-c !== $cee-c, and I think they should as both have been assigned to a reference of a static. It would seem to be a bug. I get the same output for V5.0.0 to V5.3.3RC2 -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Static Class Member References
Richard Quadling wrote: On 12 July 2010 22:54, Daniel Kolbo kolb0...@umn.edu wrote: Richard Quadling wrote: On 11 July 2010 23:19, Daniel Kolbo kolb0...@umn.edu wrote: Hello PHPers, I'm having some trouble understanding some PHP behaviour. The following example script exhibits the behaviour which I cannot understand. [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; $b = new B; $cee = new C; 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) ? [/code] Why does $c-c print 'int 3' ? 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? Thanks in advance What do you think the value should be? A static property is bound to the class and not to an instance of the class. So, A::$a is a reference to the static value. If you alter the value, it will be altered for a subclasses of A and for any other reference to it. I think var_dump($c-c); would print object(B), but it's printing int 3. The reference is *not* being updated. I think this is a bug. What do you think? Thanks ` What version of PHP are you using? I'm using: PHP Version 5.2.13 -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Static Class Member References
Richard Quadling wrote: On 13 July 2010 09:46, Richard Quadling rquadl...@gmail.com wrote: On 12 July 2010 22:54, Daniel Kolbo kolb0...@umn.edu wrote: Richard Quadling wrote: On 11 July 2010 23:19, Daniel Kolbo kolb0...@umn.edu wrote: Hello PHPers, I'm having some trouble understanding some PHP behaviour. The following example script exhibits the behaviour which I cannot understand. [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; $b = new B; $cee = new C; 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) ? [/code] Why does $c-c print 'int 3' ? 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? Thanks in advance What do you think the value should be? A static property is bound to the class and not to an instance of the class. So, A::$a is a reference to the static value. If you alter the value, it will be altered for a subclasses of A and for any other reference to it. I think var_dump($c-c); would print object(B), but it's printing int 3. The reference is *not* being updated. I think this is a bug. What do you think? Thanks Aha! $c = new C; At this stage $c-c will be a reference to the static A::$a = 3. $b = new B; Now, as B's constructor calls A's constructor which replaces the static A::$a with a reference to the instance $b, the static A::$a should now be $b $cee = new C; At this stage $cee-c will be a reference to the static A::$a = $b. But, when var_dump()'d, $c-c !== $cee-c, and I think they should as both have been assigned to a reference of a static. It would seem to be a bug. I get the same output for V5.0.0 to V5.3.3RC2 Thanks for confirming. I reported the bug. I shortened up the test script quite a bit. Please see: Bug #52332 http://bugs.php.net/bug.php?id=52332 ` -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Static Class Member References
On 11 July 2010 23:19, Daniel Kolbo kolb0...@umn.edu wrote: Hello PHPers, I'm having some trouble understanding some PHP behaviour. The following example script exhibits the behaviour which I cannot understand. [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; $b = new B; $cee = new C; 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) ? [/code] Why does $c-c print 'int 3' ? 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? Thanks in advance What do you think the value should be? A static property is bound to the class and not to an instance of the class. So, A::$a is a reference to the static value. If you alter the value, it will be altered for a subclasses of A and for any other reference to it. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Static Class Member References
Richard Quadling wrote: On 11 July 2010 23:19, Daniel Kolbo kolb0...@umn.edu wrote: Hello PHPers, I'm having some trouble understanding some PHP behaviour. The following example script exhibits the behaviour which I cannot understand. [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; $b = new B; $cee = new C; 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) ? [/code] Why does $c-c print 'int 3' ? 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? Thanks in advance What do you think the value should be? A static property is bound to the class and not to an instance of the class. So, A::$a is a reference to the static value. If you alter the value, it will be altered for a subclasses of A and for any other reference to it. I think var_dump($c-c); would print object(B), but it's printing int 3. The reference is *not* being updated. I think this is a bug. What do you think? Thanks ` -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
[PHP] Static Class Member References
Hello PHPers, I'm having some trouble understanding some PHP behaviour. The following example script exhibits the behaviour which I cannot understand. [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; $b = new B; $cee = new C; 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) ? [/code] Why does $c-c print 'int 3' ? 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? Thanks in advance ` -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php