Doctrine如何设置私有ID

Bra*_*ldt 5 php doctrine-orm

在PHP中,我可以使用私有/受保护$id变量创建模型,而不使用setter.

Doctrine ORM能够在保存/加载对象时设置该属性.

这在内部如何运作?我假设这是由序列化处理的,但我无法找到负责此行为的代码.

Col*_*n M 18

第一次doctrine实例化一个实体(例如a User)时,它会这样做:

$this->prototype = unserialize(sprintf('O:%d:"%s":0:{}', strlen($this->name), $this->name));
Run Code Online (Sandbox Code Playgroud)

在不调用其构造函数的情况下创建该类型的对象(反序列化避免调用__construct,并且他们故意这样做,因此他们不必担心构造函数的样子或者是什么).

初始化第一个对象后,Doctrine用于clone创建相同对象类型的新实例.

$entity = clone $this->prototype;
Run Code Online (Sandbox Code Playgroud)

从克隆的对象,它将:

$reflection = new \ReflectionObject($entity);
$property = $reflection->getProperty('idField');
$property->setAccessible(true);
$property->setValue($entity, 123);
Run Code Online (Sandbox Code Playgroud)

由于Doctrine对复合主键的支持,实际执行此操作的代码更为复杂,但这有助于指导您正确的方向.


Ocr*_*ius 5

Doctrine ORM使用反射分配标识符.这是在您的实体的类元数据中完成的.

当ORM必须在不使用构造函数参数的情况下在内部实例化它们时,非序列化仅用于创建实体的新实例(蓝图).一旦蓝图可用,就会为每个新请求的实例克隆它.

官方网站上有一个博客文章,解释了Doctrine如何创建实体的新实例.