Doctrine 2 需要将从数据库中获取的数据转换为实体(php 对象)。这个过程称为水合作用。
Doctrine 2 没有使用传统的使用new
操作符的方法(从而构造一个类),而是使用了以下方法:
- 它构建了一个字符串,该字符串表示您的类的序列化空版本。
- 它反序列化该字符串以使其成为实际对象。这就是为什么您需要安全地实施
__wakeup
.
- 它将该对象存储为原型。
这个过程对每个实体类执行一次。
然后,每当它需要对实体进行水合时,它就会克隆原型。这就是为什么您需要安全地实施__clone
.
这都是newInstance()
在ClassMetadataInfo中的一个小方法完成的。
这样做的好处是当新实体被水合时不使用构造函数。这使开发人员可以自由地在构造函数中做任何他/她想做的事情(包括使用参数)。
更新
您需要安全地实现__wakeup
and__clone
方法的原因是:
因为 Doctrine 2 在需要水合实体时会反序列化和克隆实体,因此将调用这些方法。但是当 Doctrine 2 这样做时,实体将没有任何数据集(甚至没有标识符)。数据将在之后设置。
因此,当您以仅在实体确实具有标识符时执行您的逻辑的方式实现它们时,您确定您的逻辑仅在您反序列化或克隆实体时执行,而不是在 Doctrine 2 执行时执行。