php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #69677 External attribute specifies a reference to an object, clone the original objec
Submitted: 2015-05-21 07:10 UTC Modified: 2015-05-26 10:22 UTC
From: ttlxihuan at 163 dot com Assigned: cmb (profile)
Status: Not a bug Package: Scripting Engine problem
PHP Version: 5.6.9 OS: window,linux
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: ttlxihuan at 163 dot com
New email:
PHP Version: OS:

 

 [2015-05-21 07:10 UTC] ttlxihuan at 163 dot com
Description:
------------
class a{
    public $n;
    public function __construct($n)
    {
        $this->n=$n;
        $N=&$this->n;
    }
}
class b{
    public $n;
    public function __construct($n)
    {
        $this->n=$n;
    }
}
class c{
    public function t($b){
        $cb=  clone $b;
        $cb->n='clone';
        var_dump($cb->n,$b->n);
    }
}

Test script:
---------------
$c=new c();
$a=new a('new');
$b=new b('new');
$n=&$b->n;
//Class A specified reference when constructing, clone and modify the properties of the original object has no effect
$c->t($a);
//Class B specified external references, clone modify properties directly affect the original object properties
$c->t($b);

Expected result:
----------------
I may be wrong envisioned, I believe that adding a reference to the cloned object should be completely independent and does not affect the original object property values.The end result should be:

string(5) "clone"
string(3) "new"
string(5) "clone"
string(5) "new" 

Actual result:
--------------
#Result:

string(5) "clone"
string(3) "new"
string(5) "clone"
string(5) "clone" 

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-05-24 22:21 UTC] cmb@php.net
-Status: Open +Status: Not a bug -Assigned To: +Assigned To: cmb
 [2015-05-24 22:21 UTC] cmb@php.net
The manual page on object cloning[1] clarifies the issue:

| When an object is cloned, PHP 5 will perform a shallow copy of
| all of the object's properties. Any properties that are
| references to other variables, will remain references.

If you slightly modify your test script, so that the reference to
A::$n is preserved, you get the same result:
<http://3v4l.org/NRTJZ>.

[1] <http://php.net/manual/en/language.oop5.cloning.php>
 [2015-05-25 03:40 UTC] ttlxihuan at 163 dot com
I may express not very good, I think the most surprising is "$n = &$b->n;" phrase program, supposedly "$b->n" should not be a reference variable, "$n" is cited variable, but after clone "$b" to modify the clone "$cb->n = 'clone';", the original "$cb->n" should not be a reference, it should be "$b->n" replica, but modifying the properties of clone has affected the value of "$b->n" is. The same operation "$N = &$this->n;" in the constructor __construct then clone, clone modify properties of an object does not affect the properties of the original object. Is it because the object attribute is an external reference, as long as the reference variable life cycle after changing the clone will change the properties of an object as a reference?
 [2015-05-26 10:22 UTC] cmb@php.net
I suggest you read the chapter on reference counting basics[1] in
the manual. As soon as a reference to variable is created (&
operator), is_ref becomes true. If all references are gone, is_ref
becomes false again. clone simply makes a shallow copy of an
object, and leaves is_ref alone. So when a property of a clone
where is_ref is true is modified, the property of the original
object is also modified (because they are actually the same
variable).

[1] <http://php.net/manual/en/features.gc.refcounting-basics.php>
 
PHP Copyright © 2001-2026 The PHP Group
All rights reserved.
Last updated: Tue Oct 06 11:00:02 2026 UTC