php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #12775 Incorrect result using references and objects
Submitted: 2001-08-15 18:00 UTC Modified: 2003-01-18 15:03 UTC
From: wayne at webmotif dot com Assigned:
Status: Wont fix Package: Scripting Engine problem
PHP Version: 4.0.6 OS: All
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2001-08-15 18:00 UTC] wayne at webmotif dot com
If you set a property of an object to a global variable, it is no longer possible to make a copy of that object! Every "copy" becomes a reference.  Example:

--/ snip /--

class foo
{
	function foo()
	{
		$this->test = 'Test';
		$GLOBALS['test'] =& $this->test;
	}
}


$obj1 = new foo();
$copyOfObj1 = $obj1;  // Should be a copy, but is reference

$obj1->test = "changed!";
echo $copyOfObj1->test.'<br>';

--/ snip /--

The result of this code is: "changed!" but it should be "Test".  $copyOfObj1 should be a copy of $obj1, but instead it acts like a reference.

If you unset $GLOBALS['test'] then it copies as it should.

This is a bug occurs in all versions of PHP4 on all platforms (from what I can tell).  

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2001-08-15 18:11 UTC] jeroen@php.net
Shallow copying of objects and arrays bit you...

Will be fixed in PHP 5

Suspended (it could be called a 'feature' though...)
 [2001-08-16 16:44 UTC] wayne at webmotif dot com
Actually, that would be a nice feature.  If one could call a function on an object such as "make_reference($this)" to change the assignment semantics for an object it would be a great way to maintain backward compatibility but let new objects be assign-by-reference.  

Anyway, the following function will do a deep copy of the object to get around this bug (if you didn't use the words "shallow copy" I wouldn't have thought of it):

function copy_object($object)
{
	$copy = $object;
	$properties = get_object_vars($object);
	foreach($properties as $name => $value) {
		if (is_object($value)) $copy->$name = copy_object($value);
		else $copy->$name = $value;
	}
	return $copy;
}
 [2001-08-16 18:14 UTC] jeroen@php.net
I always use a 'cool' workaround (forgot to mention it), it isn't extremely fast, it is simple... works on both objects, arrays, and mixes. It also preserves internal references ($obj->a =& $obj->b)

The workaround?

// $a = $b should have worked like this:
function deep_copy(&$a,&$b)
{
$a = unserialize(serialize($b));
}

 [2002-12-06 19:57 UTC] sniper@php.net
reclassified. And this is actually fixed in ZE2 already..?

 [2003-01-18 15:03 UTC] moriyoshi@php.net
Variant of bug #20175

 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Sun Nov 19 01:31:42 2017 UTC