php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #30787 Object converts to reference on method use
Submitted: 2004-11-15 00:36 UTC Modified: 2005-04-06 06:56 UTC
Votes:3
Avg. Score:5.0 ± 0.0
Reproduced:3 of 3 (100.0%)
Same Version:1 (33.3%)
Same OS:1 (33.3%)
From: php dot net at nanonanonano dot net Assigned: andi (profile)
Status: Not a bug Package: Scripting Engine problem
PHP Version: 4.3.9 OS: Debian Sarge
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 dot net at nanonanonano dot net
New email:
PHP Version: OS:

 

 [2004-11-15 00:36 UTC] php dot net at nanonanonano dot net
Description:
------------
If I instantiate an object using 'new' and then copy it, I get a true copy of the object.

If I then use a method within that object, the next time I copy it, I only get a reference not an object. 

This behaviour is inconsistent (the behaviour of the = operator depends on whether a method has been called or not) and annoying (it prevents creating a prototype object by customising it after it has been instantiated and then replicating it as needed).

I have read in other similar bug reports that "it's not a bug, it's a feature", but that response misses three important points:

* it reduces functionality (cannot replicate a proto-object)

* the behaviour is inconsistent and the programmer has no way of knowing whether the = operator will perform a copy by value or a copy by reference on member-objects within an object without doing a lot of code auditing (and one small change elsewhere in the code, might have significant side-effects)

* It is not documented *anywhere* in the php manual. I know... I've just wasted my entire weekend trying to find some way of working around this problem.

Please don't just blow me off on this one as "NOTABUG", please think about the functionality that is supposed to be here for the poor shmuck programmer! While I personally believe this is a bug in the way PHP handles objects (cf. any other OO-language), it is at the very least a bug against the documentation.


-----------
For those googling on this problem, the example code has one workaround (no doubt there are others) for a 'safe' way of touching member variables that are objects so that they do not get stuffed up and magically convert to references. For non-const methods, one can copy the member, run whatever methods are required on the copy, and then copy it back over the member-object:

function safeAlter($newValue) {
  //another horrible hack: why can't we just do
  //$this->alterB($newvalue);
  $acopy = $this->a;
  $acopy->alterB($newValue);
  $this->a = $acopy;
}

Or you can use serialize() and unserialize() to copy objects to make sure they are copied by value without any magic references appearing (horrible and liable to break many other things, but it will probably work...).

Reproduce code:
---------------
class BB {
  var $b="original value\n";
  function BB() {}
  function echoB() { echo $this->b; }
}

class AA {
  var $a;
  function AA() { $this->a = new BB(); }
  function unsafeEcho() { $this->a->echoB(); }
  function safeEcho() {
    $acopy = $this->a;
    $acopy->echoB();
  }
}

$protoA = new AA();
$a2 = $protoA;
$protoA->unsafeEcho();
$a3 = $protoA;
$a3->a->b="a new copy\n";
echo $protoA->a->b;

Expected result:
----------------
Objects $a2 and $protoA are completely independent objects as  $a2 has been created the by copy-by-value assignment operator (=).

Objects $a3 and $protoA should also be different as the code to create $a3 from $protoA is the same as for $a2.

Changing $a2 should not alter $protoA as $a2 was created from  $protoA by copy-by-value assignment. Similarly, changing $a3 should not alter $protoA.

Expected output:
---8<---
original value
original value


Actual result:
--------------
Objects $a2 and $protoA are completely independent objects as  $a2 has been created the by copy-by-value assignment operator (=).

Objects $a3 and $protoA are *not* different even though the code to create $a3 is the same.... one of the members of $protoA has mysteriously changed itself into a reference from a value!?

Changing $a2 does not alter $protoA as expected.

Changing $a3 mysteriously alters $protoA as one of the members of $protoA has mysteriously changed itself into a reference from a value!?

Actual output:
---8<---
original value
a new copy


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2004-11-27 14:53 UTC] tony2001@php.net
It seems to me, that some magic with refernces is causing this problem.
Here is simplified reproduce code:
<?
class B {
  var $b="original value\n";
  function echoB() { echo $this->b; }
}

class A {
  var $a;
  function A() { $this->a = new B(); }
}

$c = new A();
$c->a->echoB(); //comment this
var_dump($c);
$e = $c;
$e->a->b="a new copy\n";
var_dump($c);
?>
Comment marked line to see expected result.
 [2005-02-04 12:52 UTC] ericvanblokland at gmail dot com
I think this report is a duplicate of 24485
http://bugs.php.net/bug.php?id=24485
 [2005-04-05 22:23 UTC] tony2001@php.net
Duplicate of bug #24485.
 [2005-04-06 02:05 UTC] php dot net at nanonanonano dot net
How is this now "bogus", when it has been confirmed by several people and has been fixed in PHP5?

It is customary to explain with a comment when changing the status of a bug...
 [2005-04-06 06:56 UTC] tony2001@php.net
This is the very same problem that is already described in bug #24485. What else should I add ?
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Mon Jul 28 10:00:03 2025 UTC