php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #27399 Object copy neither shallow nor deep
Submitted: 2004-02-25 16:39 UTC Modified: 2004-02-25 20:41 UTC
From: php dot bugs at darwin dot no-ip dot com Assigned:
Status: Not a bug Package: Scripting Engine problem
PHP Version: 4.3.4 OS: Linux 2.4.18
Private report: No CVE-ID: None
 [2004-02-25 16:39 UTC] php dot bugs at darwin dot no-ip dot com
Description:
------------
Copying an object doesn't appear to work as expected for either a shallow or a deep copy.  

Reproduce code:
---------------
class Dummy {}

$listA = new Dummy();
$listA->next = new Dummy();
$listA->next->previous =& $listA;
$listA->value = "one";
$listA->next->value = "two";
$listA->next->previous->value = "ONE";
echo "ListA: ";
echo "(" . $listA->value . ", " . $listA->next->value . ") \n";

$listB = $listA;
$listB->value = "three";
$listB->next->value = "four";
$listB->next->previous->value="THREE";
echo "(modified listB)\n";
echo "ListA: ";
echo "(" . $listA->value . ", " . $listA->next->value . ") \n";
echo "ListB: ";
echo "(" . $listB->value . ", " . $listB->next->value . ") \n";

Expected result:
----------------
Expected output: (ie: if PHP does a deep copy)
    ListA: (ONE, two) 
    (modified listB)
    ListA: (ONE, two) 
    ListB: (three, four) 

This should happen because $listB->next->previous is a copy of the reference 
to $listA.  Modifying it should not modify ListA OR ListB.  

Possible (wrong) output: (if PHP had done a shallow copy)
    ListA: (ONE, two) 
    (modified listB)
    ListA: (THREE, four) 
    ListB: (three, four) 

This would be the case because listB's next would be a reference to ListA's 
next.


Actual result:
--------------
Actual output:
    ListA: (ONE, two) 
    (modified listB)
    ListA: (THREE, two) 
    ListB: (three, four) 

This looks like PHP did something between a shallow and a deep copy.
while ListB->next is a copy, ListB->next->previous still points at ListA. (!?!)

... For an added bonus, try replacing '= new' with '=& new' and it looks like
PHP does a shallow copy.  From my reading of PHP documentation, I thought PHP would always do deep (de-referencing) copies.  


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2004-02-25 19:30 UTC] sniper@php.net
To get the expected result, change every "= new" to "=& new".

 [2004-02-25 20:41 UTC] php dot bugs at darwin dot no-ip dot com
How is that not a bug?  Documentation leads the user to believe that "= new" and "=& new"  only differ in efficiency.

While I see that copying an object with references inside of it might break those references, Dummy() has no internal references.  It seems the copy of Dummy() should work just as well as the original.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Sat Aug 16 22:00:02 2025 UTC