【问题标题】:Clone is not working for me?克隆对我不起作用?
【发布时间】:2011-06-25 00:02:28
【问题描述】:

我有一个对象 $objDummy 属于某个类 ClassDummy,另一个对象是

$objClone = clone $objDummy;

然后我对$objClone进行任何更改,$objDummy也更改了。 我不想那样做。 我怎样才能让它工作?

编辑: 作为对克里斯的回应。 这是一个例子

<?php
class myAnotherObject{
    public $myAnotherVar =10;
}

class myObject {
    public $myVar = false;
    function __construct() {
        $this->myVar = new myAnotherObject();
    }
}


$nl = "\n";
//*
$nl = '<br />';
//*/


$obj1 = new myObject();
echo 'obj1->myVar->myAnotherVar: '.$obj1->myVar->myAnotherVar;

$obj2 = clone $obj1;

echo $nl.'obj1->myVar->myAnotherVar: '.$obj1->myVar->myAnotherVar.', obj2->myVar->myAnotherVar: '.$obj2->myVar->myAnotherVar;

$obj2->myVar->myAnotherVar = 20;
echo $nl.'obj1->myVar->myAnotherVar: '.$obj1->myVar->myAnotherVar.', obj2->myVar->myAnotherVar: '.$obj2->myVar->myAnotherVar;

输出是

obj1->myVar->myAnotherVar: 10
obj1->myVar->myAnotherVar: 10, obj2->myVar->myAnotherVar: 10
obj1->myVar->myAnotherVar: 20, obj2->myVar->myAnotherVar: 20

【问题讨论】:

  • 请注意:克隆不需要 () 大括号,因为它不是函数,但更像“新”运算符

标签: php clone


【解决方案1】:

你可以这样做,但不能用于带有方法的对象 ->

function cloneObj(&obj) {
 return json_decode(json_encode($obj));
}

$a = new stdClass();
$b = cloneObj($a);

【讨论】:

    【解决方案2】:

    您是否正在实施__clone() 方法? PHP documentation on cloning 中的示例将比我可能更好地解释这一点。具体来说你对这部分感兴趣,

    当一个对象被克隆时,PHP 5 将 执行所有的浅拷贝 对象的属性。任何属性 是对其他的引用 变量,将保持引用。

    克隆完成后,如果 __clone() 方法被定义,然后新创建的对象的 __clone() 方法将被调用,以允许任何 需要的必要属性 改变了。

    更新
    根据您对问题的更新,您确实缺少__clone() 的实现。由于myObject$myVar 成员本身就是一个对象,因此您也需要克隆它。这是你的myObject 类应该是什么样子的,

    class myObject {
        public $myVar = false;
        function __construct() {
            $this->myVar = new myAnotherObject();
        }
    
        function __clone() {
            $this->myVar = clone $this->myVar;
        }
    }
    

    然后输出变成如下,

    obj1->myVar->myAnotherVar: 10
    obj1->myVar->myAnotherVar: 10, obj2->myVar->myAnotherVar: 10
    obj1->myVar->myAnotherVar: 10, obj2->myVar->myAnotherVar: 20
    

    【讨论】:

    • 请再次检查问题。让我知道我怎样才能得到解决方案。
    • 天啊,解决方案如此简单。我一定仔细阅读了文档。无论如何感谢您的帮助。
    【解决方案3】:

    我无法复制您的结果。使用下面的代码,我得到了预期的输出(复制到代码下面)。如图所示,这不需要 ___clone() 方法。你能发布一个精简版的代码吗?

    代码

    class myObject {
        public $myVar = false;
        function __construct($newVar=5) {
            $this->myVar = $newVar;
        }
    }
    
    $nl = "\n";
    //*
    $nl = '<br />';
    //*/
    
    
    $obj1 = new myObject(10);
    echo 'obj1->myVar: '.$obj1->myVar;
    
    $obj2 = clone $obj1;
    echo $nl.'obj1->myVar: '.$obj1->myVar.', obj2->myVar: '.$obj2->myVar;
    
    $obj1->myVar = 20;
    echo $nl.'obj1->myVar: '.$obj1->myVar.', obj2->myVar: '.$obj2->myVar;
    

    输出

    obj1->myVar: 10
    obj1->myVar: 10, obj2->myVar: 10
    obj1->myVar: 20, obj2->myVar: 10
    

    讨论后编辑:

    您的问题是由对对象的引用引起的。由于所有对象都是通过引用处理的,所以当您克隆一个对象时,您还需要克隆任何内部持有的对象,否则您最终会得到对单个对象的引用。

    代码

    class myAnotherObject{
        public $myAnotherVar =10;
    }
    
    class myObject {
        public $myVar = false;
        function __construct() {
            $this->myVar = new myAnotherObject();
        }
        function __clone() {
            $this->myVar = clone $this->myVar;  
        }
    }
    
    
    $nl = "\n";
    //*
    $nl = '<br />';
    //*/
    
    
    $obj1 = new myObject();
    echo 'obj1->myVar->myAnotherVar: '.$obj1->myVar->myAnotherVar;
    
    $obj2 = clone $obj1;
    
    echo $nl.'obj1->myVar->myAnotherVar: '.$obj1->myVar->myAnotherVar.', obj2->myVar->myAnotherVar: '.$obj2->myVar->myAnotherVar;
    
    $obj2->myVar->myAnotherVar = 20;
    echo $nl.'obj1->myVar->myAnotherVar: '.$obj1->myVar->myAnotherVar.', obj2->myVar->myAnotherVar: '.$obj2->myVar->myAnotherVar;
    

    输出

    obj1->myVar->myAnotherVar: 10
    obj1->myVar->myAnotherVar: 10, obj2->myVar->myAnotherVar: 10
    obj1->myVar->myAnotherVar: 10, obj2->myVar->myAnotherVar: 20
    

    【讨论】:

    • @Rich Adams 是正确的。我将编辑我的答案以进行演示。 __clone() 方法会照顾好你。 :)
    猜你喜欢
    • 1970-01-01
    • 2016-12-12
    • 1970-01-01
    • 1970-01-01
    • 2016-09-08
    • 2013-06-12
    • 2018-12-12
    • 1970-01-01
    • 2016-02-01
    相关资源
    最近更新 更多