看来PHP对象是通过引用传递的。甚至赋值运算符似乎也没有创建Object的副本。
这是一个简单,人为的证明:
<?php
class A {
public $b;
}
function set_b($obj) { $obj->b = "after"; }
$a = new A();
$a->b = "before";
$c = $a; //i would especially expect this to create a copy.
set_b($a);
print $a->b; //i would expect this to show 'before'
print $c->b; //i would ESPECIALLY expect this to show 'before'
?>
在两个印刷案例中,我都在'之后'
那么,我如何按价值而不是按参考将 $ a 传递给 set_b() ?
答案 0 :(得分:244)
在PHP 5+对象中通过引用传递。在PHP 4中,它们是按值传递的(这就是为什么它通过引用传递运行时的原因,它已被弃用)。
您可以使用PHP5中的'clone'运算符来复制对象:
$objectB = clone $objectA;
此外,它只是通过引用传递的对象,而不是您在问题中所说的所有内容......
答案 1 :(得分:90)
答案常见于Java书籍。
克隆: 如果不重写克隆方法,则默认行为为浅副本。如果你的对象只有原始成员变量,那就完全可以了。但是在使用另一个对象作为成员变量的无类型语言中,这很令人头疼。
序列化/反序列化
$new_object = unserialize(serialize($your_object))
这取决于对象的复杂程度,实现了深度复制,成本高昂。
答案 2 :(得分:18)
根据之前的评论,如果您有另一个对象作为成员变量,请执行以下操作:
class MyClass {
private $someObject;
public function __construct() {
$this->someObject = new SomeClass();
}
public function __clone() {
$this->someObject = clone $this->someObject;
}
}
现在你可以进行克隆:
$bar = new MyClass();
$foo = clone $bar;
答案 3 :(得分:9)
根据文档(http://ca3.php.net/language.oop5.cloning):
$a = clone $b;
答案 4 :(得分:4)
为了澄清PHP使用copy on write,所以基本上一切都是引用,直到你修改它,但对于对象你需要使用clone和__clone()魔术方法,就像在接受的答案中一样。
答案 5 :(得分:1)
此代码有助于克隆方法
class Foo{
private $run=10;
public $foo=array(2,array(2,8));
public function hoo(){return 5;}
public function __clone(){
$this->boo=function(){$this->hoo();};
}
}
$obj=new Foo;
$news= clone $obj;
var_dump($news->hoo());
答案 6 :(得分:1)
我正在做一些测试并得到了这个:
class A {
public $property;
}
function set_property($obj) {
$obj->property = "after";
var_dump($obj);
}
$a = new A();
$a->property = "before";
// Creates a new Object from $a. Like "new A();"
$b = new $a;
// Makes a Copy of var $a, not referenced.
$c = clone $a;
set_property($a);
// object(A)#1 (1) { ["property"]=> string(5) "after" }
var_dump($a); // Because function set_property get by reference
// object(A)#1 (1) { ["property"]=> string(5) "after" }
var_dump($b);
// object(A)#2 (1) { ["property"]=> NULL }
var_dump($c);
// object(A)#3 (1) { ["property"]=> string(6) "before" }
// Now creates a new obj A and passes to the function by clone (will copied)
$d = new A();
$d->property = "before";
set_property(clone $d); // A new variable was created from $d, and not made a reference
// object(A)#5 (1) { ["property"]=> string(5) "after" }
var_dump($d);
// object(A)#4 (1) { ["property"]=> string(6) "before" }
?>
答案 7 :(得分:0)
在此示例中,我们将创建 iPhone 类,并通过克隆
从中进行精确复制class iPhone {
public $name;
public $email;
public function __construct($n, $e) {
$this->name = $n;
$this->email = $e;
}
}
$main = new iPhone('Dark', 'm@m.com');
$copy = clone $main;
// if you want to print both objects, just write this
echo "<pre>"; print_r($main); echo "</pre>";
echo "<pre>"; print_r($copy); echo "</pre>";
答案 8 :(得分:-1)
如果要完全复制其他实例中对象的属性,可能需要使用此技术:
将其序列化为JSON,然后将其反序列化为Object。