在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()
设置的值?
答案 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中它们是按值传递的。
这就是为什么提供的示例中的代码有效的原因。