Doctrine如何设置私有ID

时间:2013-02-20 13:39:03

标签: php doctrine-orm

在PHP中,我可以创建一个带有私有/受保护$id变量且没有setter的模型。

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

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

2 个答案:

答案 0 :(得分:17)

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

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

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

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

$entity = clone $this->prototype;

从克隆的对象中,它将:

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

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

答案 1 :(得分:5)

Doctrine ORM使用reflectionassign identifiers。这是在您实体的class metadata中完成的。

当ORM必须在不使用构造函数参数的情况下在内部实例化它们时,实体的非序列化is only used to create new instances(蓝图)。一旦蓝图可用,就会为每个新请求的实例克隆它。

您的实体的官方网站explaining how Doctrine creates new instances上有一个博客帖子。