【问题标题】:How does Doctrine populate id property of an Entity after successful insert/persist operation?成功插入/持久操作后,Doctrine 如何填充实体的 id 属性?
【发布时间】:2016-09-23 15:17:23
【问题描述】:

使用 ORM

$timer = new Timer();  //an object marked as a Doctrine Entity
$this->em->persist($timer);
print $timer->getId(); //blank - not yet set
$this->em->flush($timer);
print $timer->getId(); //prints ID of newly inserted record

实际的 ORM 代码(学说)

public function persist($entity)
{
    if ( ! is_object($entity)) {
        throw ORMInvalidArgumentException::invalidObject('EntityManager#persist()' , $entity);
    }

    $this->errorIfClosed();

    $this->unitOfWork->persist($entity);
}

问题

当上面的 ORM 代码没有“按引用传递”指令时,Doctrine 如何将insert_id 插入到Entity 中?

即通常我会期待这样的事情:

public function persist(&$entity)
{
    ...
}

表示将在persist 过程中修改实体(使用insert_id)。但没有任何东西。然而,Entity 神奇地填充了insert_id

这究竟是怎么发生的?

【问题讨论】:

    标签: php doctrine-orm doctrine persist last-insert-id


    【解决方案1】:

    对象通过引用传递(和分配)。无需使用运营商地址。

    经常提到的 PHP 5 OOP 的一个关键点是“对象默认通过引用传递”。这并不完全正确。本节通过一些例子来纠正这种普遍的想法。

    PHP 引用是一个别名,它允许两个不同的变量写入同一个值。从 PHP 5 开始,对象变量不再包含对象本身作为值。它只包含一个对象标识符,允许对象访问者找到实际对象。当一个对象通过参数发送、返回或分配给另一个变量时,不同的变量不是别名:它们持有标识符的副本,它指向同一个对象。

    PHP documentation

    ID 设置在UnitOfWork::executeInserts

    $postInsertIds = $persister->executeInserts();
        if ($postInsertIds) {
            // Persister returned post-insert IDs
            foreach ($postInsertIds as $postInsertId) {
                $id      = $postInsertId['generatedId'];
                $entity  = $postInsertId['entity'];
                $oid     = spl_object_hash($entity);
                $idField = $class->identifier[0];
                $class->reflFields[$idField]->setValue($entity, $id);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-10
      • 2016-04-13
      • 1970-01-01
      相关资源
      最近更新 更多