[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