By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,502 Members | 1,204 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,502 IT Pros & Developers. It's quick & easy.

Learning PHP (5) -> cloning objects?

P: n/a
Tom
Hey ho,

The release of PHP5 seemed like a good reason to try to learn it once
more...

I'm reading through the O'Reilly PHP/MySQL book and right now, I'm
fiddling with objects. I just discovered the proper way to clone
objects is *not* "$b = $a->__clone();", as it reads in the book, but
"$b = clone $a". Right?

Now it's still not fully clear to me. The class is called UnitCounter,
two private variables are $units and $weightPerUnit. The __clone()
function simply looks like...

$this->weightPerUnit = $that->weightPerUnit;
$this->units = $that->units;

....but when I use it like so:

$a = new UnitCounter();
$a->add(5);
$c = clone $a;
$c->add(5);

....both end up containing 5 units, whereas I would expect $c to contain
5 already from the beginning (as it's a clone of $a, which contains 5
units), so 10 in total, after adding another 5. Why is $c getting the
initial (constructor) value of zero, instead of 5 like $a, which it is
cloned from?

Hoping for someone to enlighten me,
greets,
Tom
Jul 17 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
Tom wrote:
I'm reading through the O'Reilly PHP/MySQL book and right now, I'm
fiddling with objects. I just discovered the proper way to clone
objects is *not* "$b = $a->__clone();", as it reads in the book, but
"$b = clone $a". Right?

Correct, some information from the books published before the final release
of PHP 5 is now deprecated
...both end up containing 5 units, whereas I would expect $c to
contain 5 already from the beginning (as it's a clone of $a, which
contains 5 units), so 10 in total, after adding another 5. Why is $c
getting the initial (constructor) value of zero, instead of 5 like
$a, which it is cloned from?


This is correct behavior, because a clone is a shallow copy of an object
with all properties set to their initial values.

Simple use "$b = $a" if you want to have a full copy of $a.
JW

Jul 17 '05 #2

P: n/a
Tom wrote:
I'm reading through the O'Reilly PHP/MySQL book and right now, I'm
fiddling with objects. I just discovered the proper way to clone
objects is *not* "$b = $a->__clone();", as it reads in the book, but
"$b = clone $a". Right?
Right. clone then calls the __clone method.
Now it's still not fully clear to me. The class is called UnitCounter,
two private variables are $units and $weightPerUnit. The __clone()
function simply looks like...

$this->weightPerUnit = $that->weightPerUnit;
$this->units = $that->units;

...but when I use it like so:

$a = new UnitCounter();
$a->add(5);
$c = clone $a;
$c->add(5);

...both end up containing 5 units, whereas I would expect $c to contain
5 already from the beginning (as it's a clone of $a, which contains 5
units), so 10 in total, after adding another 5. Why is $c getting the
initial (constructor) value of zero, instead of 5 like $a, which it is
cloned from?


I think you got $this and $that confused in your __clone method. Remember
that $this still refers to the current object and $that refers to the new
clone. So, your assignments should read:

$that->weightPerUnit = $this->weightPerUnit;
$that->units = $this->units;

Also, the default __clone method (without your specific implementation)
should copy all properties on its own already. If you need a different
behavior to set your own property values, only then do you need to define
your own __clone method.
Jul 17 '05 #3

P: n/a
Janwillem Borleffs wrote:
This is correct behavior, because a clone is a shallow copy of an object
with all properties set to their initial values.
If that were the case, what would be the purpose of cloning? You could just
instantiate a new object instead. clone copies all properties by default.
From http://www.php.net/manual/en/language.oop5.cloning.php

"When the developer asks to create a new copy of an object, PHP 5 will check
if a __clone() method has been defined or not. If not, it will call a
default __clone() which will copy all of the object's properties. If a
__clone() method is defined, then it will be responsible to set the
necessary properties in the created object. For convenience, the engine
will supply a function that imports all of the properties from the source
object, so that they can start with a by-value replica of the source
object, and only override properties that need to be changed."
Simple use "$b = $a" if you want to have a full copy of $a.


That's true in PHP4 but no longer true in PHP5.
Jul 17 '05 #4

P: n/a
Tom
* [Saturday 31 July 2004 00:02] Zurab Davitiani in comp.lang.php:

<snip>
Why is $c getting the initial (constructor) value of zero, instead
of 5 like $a, which it is cloned from?
I think you got $this and $that confused in your __clone method.
Remember that $this still refers to the current object and $that
refers to the new clone. So, your assignments should read:

$that->weightPerUnit = $this->weightPerUnit;
$that->units = $this->units;


Hmpf... You're right.
Also, the default __clone method (without your specific
implementation) should copy all properties on its own already.


And again... Both ways indeed work as expected.

Thanks a lot,
Tom

Jul 17 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.