php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #29441 After copying a class, changes to new class affect old class.
Submitted: 2004-07-29 08:44 UTC Modified: 2004-08-31 04:14 UTC
From: php at cyruslesser dot com Assigned:
Status: Not a bug Package: Class/Object related
PHP Version: 5.* OS: *
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: php at cyruslesser dot com
New email:
PHP Version: OS:

 

 [2004-07-29 08:44 UTC] php at cyruslesser dot com
Description:
------------
This may just be my mis-understanding of how the language should work, but surely when you copy an object (class) and make changes to it, those changes shouldn't affect the original object?   

I don't really see the point in making a copy of an object, if the changes you make to the new copy affect the old copy.

If I'm just dumb, then I apologise.

Reproduce code:
---------------
<?

class c {
   var $i = 0;
};

$a = new c;
$a->i = 1;

$b = $a;
$b->i = 2;

echo "a: $a->i";
echo "b: $b->i";

?>

Expected result:
----------------
a: 1
b: 2

Actual result:
--------------
a: 2
b: 2

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2004-08-02 12:56 UTC] derick@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

.
 [2004-08-02 14:21 UTC] php at cyruslesser dot com
Well, in version 4.3.8, it returns

a: 1
b: 2

In version 5.0.0 it returns (without error or notification)

a: 2
b: 2

That may or may not be intentional, but if there's a way to copy an object instead of a pointer to an object, I can't find it in the manual.

Cyrus Lesser
 [2004-08-02 18:24 UTC] helly@php.net
You don't copy a class, you copy an instance.
And since PHP 5.0.0 you no longer copy by value but instead by object id.
 [2004-08-03 03:26 UTC] php at cyruslesser dot com
Yes, why must everyone I ask about this point out the blatantly obvious when I ask about this?  :)

It's passing classes by reference (or pointer if you prefer the C analog) not by value.  I get it.  Honestly I do.   I just don't get why.

Please, is there a way I can quickly copy an object?  Where is memcpy()?  Why can't I call clone() directly?  Are the new functions to aid in the duplication of objects by value?  

I'm assuming that they do exist, and that I just don't know about them.  I have faith in you guys... your language is the easiest and most intuitive language I have ever seen, and I love it.   

But what I do not understand why you have chosen to do this, or how it aids the language.

I appreciate that copying a pointer (or reference) to a class is somewhat quicker than copying the entire object itself, but I don't really see how duplicating pointers is more useful that duplicating complete copies of the object.

I just don't think that a small time saving (surely it's just a few memcpy() calls) is worth the extra time it now takes when you wish to duplicate an object.  Or the problems this is going to cause with PHP4 software running under PHP5.

In PHP5, if I have an object containing data retrieved from a database, and I want to copy it, I have to instantiate a new object, and either repeat all the calls to the database to retrieve the data, or copy every member variable individually to the new class.

Either way it's slow and tedious.   But I'm very hopeful that there is a new object copy function that wasn't in the PHP5 "what's new" documentation.

I have to say, even C++ will automatically copy the contents of a class unless you override the assignment operator.

Another irksome factor about this whole thing, is the inconsistency that this brings to the language.

Previously a string object could be treated identically to a class object. 

$string1 = "a";  
$string2 = $string1;
$string2 = "b";

Which of course, will leave $string1 == "a".

But if they where class objects, then the behavior suddenly changes, and $string1 is changed.   

This is going to be very confusing to people who have never learnt a lower-level OO language before.

Even in C++ (which I would regard by today?s standard, as a pretty hard language to learn), strings and class objects behave in the same fashion when assigned, or used as arguments to functions.

While we're on the topic of functions:

In PHP4:

function ($object) {  /* pass by value */
     /* This doesn't change the original object */
     $object->change();
}

function (&$object) { /* pass by reference */
     /* This DOES change the original object */
     $object->change();
}


That made sense.  There are two different ways to pass an object, and you can chose which one you wish to use in the declaration of the function, using '&'.

In PHP5, both of those function have the same effect, they both modify the original object which is now always passed by reference.

Is this the way it's going to stay?

Cyrus Lesser
 [2004-08-03 03:30 UTC] php at cyruslesser dot com
Sorry, that was supposed to read "ARE THERE new functions to aid in the duplication of objects by value?"

Cyrus
 [2004-08-03 03:38 UTC] wez@php.net
http://zend.com/manual/migration5.oop.php
scroll down to "Objects Cloning"
 [2004-08-31 04:14 UTC] php at cyruslesser dot com
BTW, for anyone else reading this who also had trouble finding the documention, check this URL which is details the changes in the Zend 2 engine:

http://www.php.net/zend-engine-2.php

Specifically, the solution to my problem was very simple:

$new_object = clone $old_object;

Although I still feel that always forcing passing objects by reference to functions is a bit silly, I'm willing to live with it for the sake of the many great improvements to PHP5.

Thanks.

Cyrus
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Dec 27 15:01:29 2024 UTC