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