Php doctrine entity manager flush()方法是如何工作的?

Php doctrine entity manager flush()方法是如何工作的?,php,doctrine-orm,Php,Doctrine Orm,在中有以下代码: <?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 exis

在中有以下代码:

<?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
变量和
$entityManager
变量之间似乎没有任何联系,除了
$product
应该包含来自
$entityManager->find()方法的响应


$entityManager->flush()
怎么可能读取
$product->setName()
设置的值呢?

这是一个
ORM
魔术:)

但如果说真的,当您使用
原则
获取数据时,它会向对象添加大量元数据。您可以自己查看这些字段,只需
var\u dump()
对象即可

当您进行
flush()
时,
doctor
检查所有提取数据的所有字段,并向数据库进行事务处理

当您初始化一个新对象时,它没有任何
doctor
元数据,因此您必须调用另一个方法
persist()
来添加它

此外,您还可以查看
EntityManager
的功能,以更好地了解其工作原理-
原则
是一个开源项目

条令使用身份图模式跟踪目标。每当你 从数据库中获取对象时,条令将保留对 此对象位于其工作单元中。包含所有实体的数组 引用深度为两级,键为“根实体名称”和 “身份证”。因为条令允许复合密钥,所以id是一个排序的, 所有键列的序列化版本

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

这很简单,教条使用


UnityOfWork中一个有趣的方法,它计算实体是否有任何更改:

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

这就是所提供示例中的代码工作的原因


这里是详细信息:

应该有一行代码要保存:$product->setName($newName)$entityManager->persist($product)$entityManager->flush()@gvk,不,它不应该,仅当实体尚未由条令管理时才使用persist,如在
$product=new product()之后是的-看起来我错了:-(@Aerendit:你问了一个很好的问题,但我认为你应该把你的问题的标题改为更常见的,比如“flush()机制是如何工作的”或类似的东西,使这个问题对社区更有用。它是“工作单元”Doctrine有一个包含所有托管对象的注册表。当您调用$entityManager->find('Product',$id)时,创建的对象会自动添加到该不可见注册表中。当您调用flush()时,它检测哪些对象被更改,并将这些对象保存到数据库中。OP实际上错过了持久化部分-没有神奇之处:-)不,我认为一切正常,请查看我的答案的最后部分。请为您的答案添加一些解释,以便其他人可以从中学习-两者之间的区别是什么“按引用传递”和“按值传递”“与呼叫
flush
?阅读链接:它解释了一切。作为SO的长期用户,您应该知道,鼓励您在回答中给出所有解释,而不是要求人们阅读其他网站。”。尤其是当链接的文档中没有提及条令或flush的用法时
$product->setName($newName);
$entityManager->flush();