doctrine实体管理器flush()方法如何工作?

时间:2015-01-22 20:10:47

标签: php doctrine-orm

Doctrine documentation中有以下代码:

<?php
// update_product.php <id> <new-name>
require_once "bootstrap.php";

$id = $argv[1];
$newName = $argv[2];

$product = $entityManager->find('Product', $id);

if ($product === null) {
    echo "Product $id does not exist.\n";
    exit(1);
}

$product->setName($newName);

$entityManager->flush();

我不明白的是最后一部分,在使用$product->setName()设置产品名称后,调用了$entityManager->flush()方法:

$product->setName($newName);
$entityManager->flush();

在我看来,$product变量与$entityManager变量之间没有任何关联,但$product应包含来自$entityManager->find()的响应的事实除外方法

$entityManager->flush()怎样才能读取$product->setName()设置的值?

3 个答案:

答案 0 :(得分:6)

它是ORM魔法:)

但是如果认真的话,当您使用Doctrine获取数据时,它会向您的对象添加大量元数据。您可以自己查看这些字段var_dump()一个对象。

当您flush()时,Doctrine会检查所有已获取数据的所有字段,并对数据库进行交易。

初始化新对象时,它没有任何Doctrine元数据,因此您需要再调用一个persist()方法来添加它。

此外,您只需查看EntityManager的{​​{3}}即可更好地了解其工作原理 - Doctrine是一个开源项目。

答案 1 :(得分:6)

  

Doctrine使用 Identity Map 模式来跟踪对象。无论何时你   从数据库中获取一个对象,Doctrine将保留对它的引用   这个对象位于 UnitOfWork 中。包含所有实体的数组   引用是两级深度,并具有键“根实体名称”和   “ID”。由于Doctrine允许复合键,因此id是有序的,   所有关键列的序列化版本。

http://doctrine-orm.readthedocs.org/en/latest/reference/unitofwork.html

您可能会问它如何读取/写入实体的值,因为它们受到保护(如果您遵循用户指南,它们应该是这样的)!

很简单,Doctrine使用reflection

UnityOfWork中有趣的方法,用于计算实体是否有任何更改:https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/UnitOfWork.php#L560

答案 2 :(得分:-4)

所有上述回复都很好,但真正的答案是PHP5中的对象默认是通过引用传递的,而在PHP4中它们是按值传递的。

这就是为什么提供的示例中的代码有效的原因。

详情请参阅:http://php.net/manual/en/language.oop5.references.php