RE: [PHP] Static Class Member References

2010-07-14 Thread Ford, Mike
 -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

2010-07-14 Thread David Harkness
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

2010-07-14 Thread Daniel Kolbo


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

2010-07-13 Thread Richard Quadling
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

2010-07-13 Thread Richard Quadling
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

2010-07-13 Thread Daniel Kolbo
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

2010-07-13 Thread Daniel Kolbo
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

2010-07-12 Thread Richard Quadling
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

2010-07-12 Thread Daniel Kolbo
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

2010-07-11 Thread Daniel Kolbo
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