首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >什么是php中的对象克隆?

什么是php中的对象克隆?
EN

Stack Overflow用户
提问于 2010-01-27 04:07:25
回答 4查看 30.2K关注 0票数 41

有人能解释一下吗

  • 什么是php中的对象克隆?
  • 什么时候我应该在php中使用克隆关键字?
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-01-27 04:58:15

对象克隆是复制一个对象的行为。正如科迪所指出的,在PHP中的克隆是通过对对象做一个浅拷贝来完成的。这意味着克隆对象的内部对象将是而不是,除非通过定义魔术方法__clone()显式地指示对象克隆这些内部对象。

如果不使用__clone方法,则新对象的内部对象将引用内存中与克隆的原始对象的内部对象相同的对象。

考虑以下例子:

代码语言:javascript
复制
// 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;

例如,用于克隆的用例不希望外部对象扰乱对象的内部状态。

假设您有一个具有内部对象地址的类用户。

代码语言:javascript
复制
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在克隆时(如我在本文的第二个示例中)对自身进行深度复制。否则,您将头痛,试图找出为什么您的数据是错误的。

票数 41
EN

Stack Overflow用户

发布于 2010-01-27 04:51:36

克隆用于创建对象的真实副本。将对象分配给另一个变量并不会创建副本,而是创建对与对象相同的内存位置的引用:

代码语言:javascript
复制
<?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);

?>

此示例代码将输出以下内容:

代码语言:javascript
复制
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"
}
票数 27
EN

Stack Overflow用户

发布于 2010-01-27 04:13:35

对象克隆,从PHP 5的角度来看,就是所谓的“浅版”。然后,它对被克隆的对象调用__clone()方法。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2144506

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档