当前位置: 首页 > 面试题库 >

什么是PHP中的对象克隆?

戚良弼
2023-03-14
问题内容

有人可以解释一下我吗

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

  • 什么时候应该在PHP中使用clone关键字?


问题答案:

对象克隆是复制对象的行为。正如Cody所指出的那样,在PHP中进行克隆是通过对对象进行浅表复制来完成的。这意味着除非您通过定义magic方法明确指示对象也克隆这些内部对象,否则
不会 克隆已克隆对象的内部对象__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;

例如,用于克隆的用例是您不希望外部对象与对象的内部状态发生混乱的情况。

假设您有一个带有内部对象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;
    }
}

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

希望这一切都有意义。

PS .:但是
请注意,如果Address也具有内部对象,则必须通过__clone()在Address中进行定义来确保Address在克隆时复制其自身的深层副本(根据本帖子的第二个示例)。否则,您将很难尝试弄清楚数据为何被破坏。



 类似资料:
  • 问题内容: 什么是PHP中的抽象类? 如何使用? 问题答案: 抽象类是至少包含一个抽象方法的类,该方法中没有任何实际代码,只是名称和参数,并且已标记为“抽象”。 这样做的目的是提供一种模板,以从其继承并强制继承类实现抽象方法。 因此,抽象类介于常规类和纯接口之间。接口也是抽象类的特殊情况,其中所有方法都是抽象的。 有关更多参考,请参见PHP手册的这一部分。

  • 问题内容: 每当我学习垃圾收集器时,都会听到术语“对象图”。到底是什么意思? 问题答案: 对象具有对其他对象的引用,这些对象又可以具有对更多对象(包括起始对象)的引用。这将创建对象图,在可及性分析中很有用。例如,如果起始对象是可到达的(例如,它在线程的本地堆栈中),则图形中的所有对象都是可到达的,并且确切的垃圾收集器无法收集任何这些对象。同样,如果我们创建所有可到达对象的列表,则从一组活动对象(根

  • 本文向大家介绍什么是JavaScript中的arguments对象?,包括了什么是JavaScript中的arguments对象?的使用技巧和注意事项,需要的朋友参考一下 JavaScript中的Arguments对象是一个对象,代表执行函数的参数。它的语法有两个参数: 示例 您可以尝试运行以下代码来了解什么是JavaScript中的arguments对象

  • 问题内容: 您可能知道Node.js中的对象: {Object}全局名称空间对象。 在浏览器中,顶级范围是全局范围。这意味着在浏览器中,如果您位于全局作用域var中,则将定义一个全局变量。在Node中,这是不同的。顶级范围不是全局范围;var Node模块内部的某些内容对于该模块而言是本地的。 现在,我偶然发现了似乎无处记录的物体。 尽管似乎我可以使用与以下方法相同的方法: test1.js te

  • 我正在尝试对函数返回的值发出警报,并且在警报中得到以下信息: 下面是JavaScript代码: 是我试图检查的函数。

  • 问题内容: 运行python脚本时出现此错误: 我很确定’str’是字符串,但是我不知道’NoneType’对象是什么。我的脚本在第二行开始,我知道第一个行之有效,因为该行的命令符合我的期望。起初我以为可能是因为我在send_command中使用了变量和用户输入。 “ CAPS”中的所有内容都是变量,“小写”中的所有内容都是从“ parser.add_option”选项输入的。 我正在使用pexp