php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #77234 clone keyword not working as spected
Submitted: 2018-12-03 14:38 UTC Modified: 2018-12-03 16:12 UTC
From: genialjacob at gmail dot com Assigned: cmb (profile)
Status: Not a bug Package: Scripting Engine problem
PHP Version: 7.2.12 OS: Windows 10
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: genialjacob at gmail dot com
New email:
PHP Version: OS:

 

 [2018-12-03 14:38 UTC] genialjacob at gmail dot com
Description:
------------
I have a method (addFinal) in a class that copy an object from an array and put it into another, I use clone to avoid the possibility to modify the original object. 

The modification "ONLY_MODIFY_THIS" affects several objects, when is supposed to affect only the first.

I want two things:

1. Preserve original objects D1, D2 and D3

2. Modify only the object indexed in the finals array.

Test script:
---------------
class I {
  public $name;
  public $value;

  public function __construct( $name, $value )
  {
    $this->name = $name;
    $this->value = $value;
  }
}

class D {
  public $name;
  public $items;
  public function __construct( $name )
  {
    $this->name = $name;
    $this->items = array(
      'I1' => new I( "I1", 1232 ),
      'I2' => new I( "I2", 12 ),
      'I3' => new I( "I3", "hello" )
    );
  }

  public function addItem( Item $item )
  {
    array_push( $this->items, $item );
  }
}

class B {
  public $values; 
  public function __construct()
  {
    $this->values = array(
      "D1" => new D("D1"), 
      "D2" => new D("D2"), 
      "D3" => new D("D3"));
  }   
}

class A {
  public $name;
  public $bobject;
  public $finals;  
  public function __construct()
  {
    $this->bobject = new B();
    $this->finals = array();
  }
  public function addFinal( $name )
  {
    $final = clone $this->bobject->values[$name];
    array_push( $this->finals, $final );
  }
}

class C extends A {

}


$c = new C();
$c->addFinal( "D1" );
$c->addFinal( "D1" );
$c->addFinal( "D1" );
$c->addFinal( "D1" );
$c->addFinal( "D2" );
$c->addFinal( "D3" );
$c->addFinal( "D1" );

$c->finals[0]->name = "HelloWorld";
$c->finals[0]->items["I1"]->name="ONLY_MODIFY_THIS";

print_r( $c );
exit;

Expected result:
----------------
1. Preserve original objects D1, D2 and D3

2. Modify only the object indexed in the finals array.

Actual result:
--------------
The code is modifying multiple variable prevously cloned from an original object. I believe something is wrong there.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-12-03 16:12 UTC] cmb@php.net
-Status: Open +Status: Not a bug -Package: PHP Language Specification +Package: Scripting Engine problem
 [2018-12-03 16:12 UTC] cmb@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

From the docs[1]:

| When an object is cloned, PHP 5 will perform a shallow copy of
| all of the object's properties.

This is the same for PHP 7 (will fix this minor issue right away).
You are looking for a deep copy.

[1] <http://php.net/manual/en/language.oop5.cloning.php>
 [2018-12-03 16:12 UTC] cmb@php.net
-Assigned To: +Assigned To: cmb
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Apr 20 03:01:28 2024 UTC