php 什么是php中的对象克隆?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2144506/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
what is Object Cloning in php?
提问by
Can someone explain me
有人可以解释我吗
what is Object Cloning in php?
When should i use clone keyword in php?
什么是php中的对象克隆?
我什么时候应该在 php 中使用 clone 关键字?
采纳答案by Decent Dabbler
Object cloning is the act of making a copy of an object. As Codypointed out, cloning in PHP is done by making a shallow copy of the object. This means that internal objects of the cloned object will notbe cloned, unless you explicitly instruct the object to clone these internal objects too, by defining the magic method __clone().
对象克隆是制作对象副本的行为。正如Cody 所指出的,PHP 中的克隆是通过制作对象的浅拷贝来完成的。这意味着克隆对象的内部对象不会被克隆,除非您通过定义魔术方法明确指示对象也克隆这些内部对象__clone()。
If you don't utilize the __clonemethod, the internal objects of the new object will be references to the same objecs in memory as the internal objects of the original object that was cloned.
如果不使用该__clone方法,则新对象的内部对象将引用内存中与克隆的原始对象的内部对象相同的对象。
Consider these examples:
考虑以下示例:
// in this exampe the internal member $_internalObject of both objects
// reference the same instance of stdClass in memory.
class CloneableClass
{
private $_internalObject;
public function __construct()
{
// instantiate the internal member
$this->_internalObject = new stdClass();
}
}
$classA = new CloneableClass();
$classB = clone $classA;
// in this exampe the internal member $_internalObject of both objects
// DON'T reference the same instance of stdClass in memory, but are inividual instances
class CloneableClass
{
private $_internalObject;
public function __construct()
{
// instantiate the internal member
$this->_internalObject = new stdClass();
}
// on clone, make a deep copy of this object by cloning internal member;
public function __clone()
{
$this->_internalObject = clone $this->_internalObject;
}
}
$classA = new CloneableClass();
$classB = clone $classA;
Use cases for cloning would for instance be a case where you don't want outside objects to mess with the internal state of an object.
例如,克隆用例是您不希望外部对象弄乱对象内部状态的情况。
Let's say you have a class User with a internal object Address.
假设您有一个具有内部对象地址的类 User。
class Address
{
private $_street;
private $_streetIndex;
private $_city;
// etc...
public function __construct( $street, $streetIndex, $city /* etc.. */ )
{
/* assign to internal values */
}
}
class User
{
// will hold instance of Address
private $_address;
public function __construct()
{
$this->_address = new Address( 'somestreet', '1', 'somecity' /* etc */ );
}
public function getAddress()
{
return clone $this->_address;
}
}
For arguments sake, let's say you don't want outside objects to mess with the internal Address of User objects, but you do want to be able to give them a copy of the Address object. The above example illustrates this. The getAddressmethod returns a clone of the address object to calling objects. This means that if the calling object alters the Address object, the internal Address of User will not change. If you didn't give a clone, then the outside object wouldbe able to alter the internal Address of User, because a reference is given by default, not a clone.
为了论证起见,假设您不希望外部对象与 User 对象的内部 Address 混淆,但您确实希望能够为它们提供 Address 对象的副本。上面的例子说明了这一点。该getAddress方法将地址对象的克隆返回给调用对象。这意味着如果调用对象改变了地址对象,用户的内部地址不会改变。如果您没有提供克隆,则外部对象将能够更改用户的内部地址,因为默认情况下会提供引用,而不是克隆。
Hope this all makes some sense.
希望这一切都有意义。
PS.:
Be aware though, that if Address would also have internal objects, you would have to make sure Address makes a deep copy of itself on cloning (as per my second example of this post) by defining __clone()in Address. Otherwise you will get headaches of trying to figure out why your data is screwed.
PS。:但是
请注意,如果 Address 也有内部对象,则必须通过__clone()在 Address 中定义来确保 Address 在克隆时制作其自身的深层副本(根据本文的第二个示例)。否则,您会因为试图找出数据被搞砸的原因而头疼。
回答by leepowers
Cloning is used to create a genuine copy of an object. Assigning an object to another variable does not create a copy - rather, it creates a reference to the same memory location as the object:
克隆用于创建对象的真实副本。将对象分配给另一个变量不会创建副本 - 相反,它会创建对与对象相同的内存位置的引用:
<?php
$o= new stdclass;
$o->a= 'b';
$o->b= 'c';
$o2= $o;
$o2->a= 'd';
var_dump($o);
var_dump($o2);
$o3= clone $o;
$o3->a= 'e';
var_dump($o);
var_dump($o3);
?>
This example code will output the following:
此示例代码将输出以下内容:
object(stdClass)#1 (2) {
["a"]=>
string(1) "d"
["b"]=>
string(1) "c"
}
object(stdClass)#1 (2) {
["a"]=>
string(1) "d"
["b"]=>
string(1) "c"
}
object(stdClass)#1 (2) {
["a"]=>
string(1) "d"
["b"]=>
string(1) "c"
}
object(stdClass)#2 (2) {
["a"]=>
string(1) "e"
["b"]=>
string(1) "c"
}
回答by Cody Haines
Object Cloning, in terms of PHP 5, is what is known as a "shallow copy". It then calls the __clone() method on the object being cloned.
对象克隆,就 PHP 5 而言,就是所谓的“浅拷贝”。然后它在被克隆的对象上调用 __clone() 方法。
回答by cweiske
If you need a deep clone - that is, clones of the child objects and clones of the grandchild objects - you can either overwrite __clonein each of the classes, or simply serialize+unserialize the object:
如果您需要深度克隆 - 即子对象的克隆和孙对象的克隆 - 您可以__clone在每个类中覆盖,或者简单地序列化+反序列化对象:
function deepClone($object)
{
return unserialize(serialize($object));
}
回答by Matthieu Napoli
As explained in other answers, clonemakes a shallow copyof the object.
如其他答案中所述,clone制作对象的浅拷贝。
If you need to make a deep copy(i.e. recursive copy), you can overload the __clone()methods.
如果您需要进行深度复制(即递归复制),您可以重载这些__clone()方法。
You can also use this library: MyCLabs\DeepCopy, which is more simple and powerful than a simple clone.
您还可以使用这个库:MyCLabs\DeepCopy,它比简单的克隆更简单和强大。

