什么是PHP中的对象克隆? [英] what is Object Cloning in php?

查看:152
本文介绍了什么是PHP中的对象克隆?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以解释我吗

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

  • 何时应该在php中使用clone关键字?

解决方案

对象克隆是制作对象副本的行为.正如 Cody 所指出的那样,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;

例如,克隆的用例是您不希望外部对象弄乱对象内部状态的情况.

假设您有一个User类,其内部对象是Address.

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;
    }
}

出于参数的考虑,假设您不希望外部对象与User对象的内部Address混为一谈,但是您确实希望能够为它们提供Address对象的副本.上面的示例对此进行了说明. getAddress方法将地址对象的克隆返回给调用对象.这意味着,如果调用对象更改了地址对象,则用户的内部地址将不会更改.如果您不提供克隆,则外部对象将能够更改用户的内部地址,因为默认情况下会提供引用,而不是克隆.

希望这一切都有道理.

PS.
但是请注意,如果Address也具有内部对象,则必须通过在Address中定义__clone()来确保Address在克隆时对其进行深拷贝(根据本博文的第二个示例).否则,您会头疼不已,想弄清楚数据为什么被搞砸了.

Can someone explain me

  • what is Object Cloning in php?

  • When should i use clone keyword in php?

解决方案

Object cloning is the act of making a copy of an object. As Cody pointed out, cloning in PHP is done by making a shallow copy of the object. This means that internal objects of the cloned object will not be cloned, unless you explicitly instruct the object to clone these internal objects too, by defining the magic method __clone().

If you don't utilize the __clone method, 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.

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.

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 getAddress method 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 would be able to alter the internal Address of User, because a reference is given by default, not a clone.

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.

这篇关于什么是PHP中的对象克隆?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆