UPDATE
该答案包含有关代理对象和部分对象之间差异的错误信息。有关更多详细信息,请参阅@Kontrollfreak 的答案:https://stackoverflow.com/a/17787070/252591
只要您的查询未返回创建实体所需的所有数据,就会使用代理对象。想象一下以下场景:
@Entity
class User {
@Column protected $id;
@Column protected $username;
@Column protected $firstname;
@Column protected $lastname;
// bunch of setters/getters here
}
DQL query:
SELECT u.id, u.username FROM Entity\User u WHERE u.id = :id
正如你所看到的,这个查询没有返回firstname
and lastname
属性,因此您无法创建User
目的。创建不完整的实体可能会导致意外错误。
这就是为什么 Doctrine 将创造UserProxy
支持延迟加载的对象。当您尝试访问时firstname
属性(未加载)它将首先从数据库加载该值。
我的意思是为什么我应该使用代理?
您应该始终像根本不使用代理对象一样编写代码。它们可以被视为 Doctrine 使用的内部对象。
为什么实体本身不能实现延迟加载?
从技术上讲,它可能是,但看看一些随机代理对象的类。它充满了肮脏的代码,呃。在您的实体中拥有干净的代码是件好事。
您能给我提供一个用例吗?
您正在显示最新 25 篇文章的列表,并且想要显示第一篇文章的详细信息。每个数据都包含大量文本,因此获取所有数据会浪费内存。这就是为什么你不获取不必要的数据。
SELECT a.title, a.createdAt
FROM Entity\Article a
ORDER BY a.createdAt DESC
LIMIT 25
$isFirst = true;
foreach ($articles as $article) {
echo $article->getTitle();
echo $article->getCreatedAt();
if ($isFirst) {
echo $article->getContent(); // Article::content is not loaded so it is transparently loaded
// for this single article.
$isFirst = false;
}
}