NYCPHP Meetup

NYPHP.org

[nycphp-talk] Pass-by-value and lazy copy

Paul Houle paul at devonianfarm.com
Thu Nov 22 16:56:21 EST 2007


Gary Mort wrote:
> How does this work with objects?  For example:
>
> $a->foo = "Foo";
> $a->foobar = "Foobar";
>
> $b = $a;
> // at this point in time, their using the same memory location for 
> their variables
>
> $b->foobar="New Foobar";
> // Is the entire object for $b copied to a new memory location, or is 
> just $b->foobar given it's own memory?

Good question.  This is different in PHP 4 and PHP 5 -- in fact,  I 
think this is the most important difference between the versions.

The "=" operator copies objects in PHP 4 (they behave like numbers,  
strings,  etc.),  but it copies references to objects in PHP 5.

Modern OO languages such as Java,  Python and Ruby work like PHP 5.  The 
PHP 5 behavior works much better for building big object oriented 
systems -- it's much better when you put objects together to build 
bigger systems,  particularly when you end up with circular 
relationships between them.

To take an example,  imagine we have some code that looks like

$a=new ClassA();
$b=new ClassB($a);

Now,  the definition of classB looks like:

class ClassB {
    function ClassB($a) { $this->a= $a };

    function zapA() {
       $this->a->zapA();
    }
}

In PHP 5,  the $a that's inside $b and the $a in the other scope are the 
same object.  So if I write

$b->zapA();
if ($a->wasZapped()) {
   print "A got zapped";
} else {
    print "A was not zapped";
}

It's going to print "A got zapped".

That is,  I can do something to $a inside $b,  and everbody else sees 
the change.  In PHP4,  the $a inside ClassB is $b's private copy,  
$b->$a gets zapped,  but the original $a does not get zapped,  so it 
prints "A was not zapped."

PHP4 really breaks down when your objects start to have circular 
relationships -- something that happens when your code reaches a certain 
level of complexity...  For instance,  when you're working with 
frameworks.  Circular relationships aren't really circular if $a points 
to $b,  but $b has a different copy of $a,  say $a1.  PHP 4 is 
treacherous,  because things will work the way you want much of time,  
but not always...  You'll end up with real head-scratcher bugs.  By 
using the '&' operator in function calls and in assigments,  you can get 
PHP 4 to behave a lot like PHP 5,  but weird things will happen if you 
miss using '&' even once.





More information about the talk mailing list