Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 为什么在条令2中需要安全唤醒和克隆方法?_Php_Symfony_Orm_Doctrine Orm - Fatal编程技术网

Php 为什么在条令2中需要安全唤醒和克隆方法?

Php 为什么在条令2中需要安全唤醒和克隆方法?,php,symfony,orm,doctrine-orm,Php,Symfony,Orm,Doctrine Orm,该文档多次警告要确保在条令2实体上实现唤醒和克隆,例如: 但是,它没有说为什么。。。我认为这与没有弄乱Doctrine的实体管理器和它可能维护的内存缓存有关,但是粗略地深入(庞大的)代码库并没有说更多,快速搜索用户列表也没有说更多 熟悉Doctrine内部结构的任何人都可能确切地知道为什么Doctrine 2需要实体上的安全唤醒和克隆方法吗?Doctrine 2需要将从数据库获取的数据转换为实体(php对象)。这个过程叫做水合作用 条令2没有使用传统的使用new操作符的方法(从而构造一个类),

该文档多次警告要确保在条令2实体上实现唤醒和克隆,例如:

但是,它没有说为什么。。。我认为这与没有弄乱Doctrine的实体管理器和它可能维护的内存缓存有关,但是粗略地深入(庞大的)代码库并没有说更多,快速搜索用户列表也没有说更多


熟悉Doctrine内部结构的任何人都可能确切地知道为什么Doctrine 2需要实体上的安全唤醒和克隆方法吗?

Doctrine 2需要将从数据库获取的数据转换为实体(php对象)。这个过程叫做水合作用

条令2没有使用传统的使用
new
操作符的方法(从而构造一个类),但它使用了以下方法:

  • 它构建一个字符串,表示类的序列化空版本
  • 它取消序列化该字符串,使其成为实际对象。这就是为什么您需要安全地实施
    \uuu唤醒
  • 它将该对象存储为原型
此过程对每个实体类执行一次

然后,每当它需要一个实体时,它就会克隆原型。这就是为什么您需要安全地实施
\uu克隆

所有这些都是在中通过一个小方法
newInstance()
完成的

这样做的好处是,当一个新实体水合时,不使用构造函数。这使得开发人员可以自由地在构造函数中执行任何他/她想要的操作(包括使用参数)

更新

您需要安全实施
\uuu唤醒
\uu克隆
方法的原因如下:

因为条令2在需要水合时对实体进行非序列化和克隆,这些方法将被调用。但当条令2这样做时,实体将没有任何数据集(甚至没有标识符)。之后将设置数据


因此,当您以这样的方式实现它们时,您的逻辑仅在实体具有标识符时执行,您可以确定,您的逻辑仅在取消实体序列化或克隆实体时执行,而不是在原则2执行时执行。

Jasper的回答明确了确切的原因,但它并没有给出背景——比如为什么学说正在进行实体的非序列化和克隆

这样做的理由是允许实体定义他们想要的任何构造函数,如本文所述:

在Confo 2010上,在我的演讲中,有人询问了条令2中实体的构造器,以及是否可以使用它。我认为这是值得一写的,因为在教义1中这是不可能的。构造器是从你那里抢来的,由条令内部使用

在原则2中,可以在实体类中定义构造函数,而不需要是零参数构造函数!没错,条令2从不实例化实体的构造函数,所以你可以完全控制它

这是可能的,因为另外两个项目和Flow3使用了一个小技巧。其要点是,我们存储一个原型类实例,该实例是从手工制作的序列化字符串中未序列化的,其中类名连接到字符串中。当我们取消序列化字符串时,结果是该类的一个实例被存储为原型,并在每次我们需要一个新实例时进行克隆

请查看负责此操作的方法:


我添加了一个后续答案,以强调条令这样做的原因。
<?php
public function newInstance()
{
    if ($this->_prototype === null) {
        $this->_prototype = unserialize(sprintf('O:%d:"%s":0:{}', strlen($this->name), $this->name));
    }
    return clone $this->_prototype;
}