有人能解释一下吗
发布于 2010-01-27 04:58:15
对象克隆是复制一个对象的行为。正如科迪所指出的,在PHP中的克隆是通过对对象做一个浅拷贝来完成的。这意味着克隆对象的内部对象将是而不是,除非通过定义魔术方法__clone()显式地指示对象克隆这些内部对象。
如果不使用__clone方法,则新对象的内部对象将引用内存中与克隆的原始对象的内部对象相同的对象。
考虑以下例子:
// 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;例如,用于克隆的用例不希望外部对象扰乱对象的内部状态。
假设您有一个具有内部对象地址的类用户。
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;
}
}为了参数起见,假设您不希望外部对象扰乱用户对象的内部地址,但您确实希望能够给它们一个Address对象的副本。上面的例子说明了这一点。getAddress方法将address对象的克隆返回给调用对象。这意味着,如果调用对象更改Address对象,则用户的内部地址不会更改。如果您没有给出一个克隆,那么外部对象将能够更改用户的内部地址,因为引用是默认提供的,而不是克隆。
希望这一切都有意义。
PS.:
但是请注意,如果Address也有内部对象,则必须通过在Address中定义__clone()来确保Address在克隆时(如我在本文的第二个示例中)对自身进行深度复制。否则,您将头痛,试图找出为什么您的数据是错误的。
发布于 2010-01-27 04:51:36
克隆用于创建对象的真实副本。将对象分配给另一个变量并不会创建副本,而是创建对与对象相同的内存位置的引用:
<?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);
?>此示例代码将输出以下内容:
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"
}发布于 2010-01-27 04:13:35
对象克隆,从PHP 5的角度来看,就是所谓的“浅版”。然后,它对被克隆的对象调用__clone()方法。
https://stackoverflow.com/questions/2144506
复制相似问题