Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 对雄辩的动态属性的多次调用是否会多次命中数据库?_Php_Laravel_Laravel 4_Eloquent - Fatal编程技术网

Php 对雄辩的动态属性的多次调用是否会多次命中数据库?

Php 对雄辩的动态属性的多次调用是否会多次命中数据库?,php,laravel,laravel-4,eloquent,Php,Laravel,Laravel 4,Eloquent,现在,如果我这样做: echo $phone->user->email; echo $phone->user->name; echo $phone->user->nickname; 每次我使用->user动态属性时,Eloquent是否会调用数据库?或者这是否足够聪明,可以在第一次呼叫时缓存用户 在您的示例中,$phone对象上的user属性将延迟加载,但只加载一次 请记住,加载对象后,它不会反映对基础表的任何更改,除非您使用load方法手动重新加载关系 以

现在,如果我这样做:

echo $phone->user->email;
echo $phone->user->name;
echo $phone->user->nickname;

每次我使用
->user
动态属性时,Eloquent是否会调用数据库?或者这是否足够聪明,可以在第一次呼叫时缓存用户

在您的示例中,
$phone
对象上的
user
属性将延迟加载,但只加载一次

请记住,加载对象后,它不会反映对基础表的任何更改,除非您使用
load
方法手动重新加载关系

以下代码说明了该示例:

$phone = Phone::find(1);

// first use of user attribute triggers lazy load
echo $phone->user->email;

// get that user outta here.
User::destroy($phone->user->id);

// echoes the name just fine, even though the record doesn't exist anymore
echo $phone->user->name;

// manually reload the relationship
$phone->load('user');

// now will show null, since the user was deleted and the relationship was reloaded
var_export($phone->user);

一次迭代将调用
电话
用户
。您必须加载多个迭代。我相信,对
$phone->user
的第一次引用将加载
user
模型,并包含该模型的所有本地属性。假定
电子邮件
姓名
昵称
存储在
用户
中,则这将只导致两个数据库查询(一个用于电话,另一个用于用户)。试试看:在这些语句之后,运行
dd(\DB::getQueryLog())
查看所做的精确查询。@cerbiform-
dd(\DB::getQueryLog())
给了我答案:它-确实-缓存数据库调用。即使我像上面的例子那样访问它三次,也只使用一个额外的数据库查询来获取
User
对象。感谢您指出如何查看查询日志。如果你把它作为一个答案发布,我可以将它标记为这样。这意味着,即使我使用了急切加载来获取相同的数据,当我只获取一个对象时,我仍然会得到两个数据库调用。完美地总结了我关于这个的问题。谢谢。@thom是的,急切加载将至少创建两个数据库调用。但是,它可以防止n+1问题。如果您执行了
$phones=Phone::all()
,然后foreach遍历所有phone对象并显示用户名,它将执行一次查询以获取所有phone,然后为每个循环迭代执行一次单独的用户查询(n+1)。但是,如果您通过执行
$phones=Phone::with('user')->get()来进行加载
,并运行相同的foreach,总共只进行2次数据库调用,一次用于电话,一次用于所有相关用户。
$phone = Phone::find(1);

// first use of user attribute triggers lazy load
echo $phone->user->email;

// get that user outta here.
User::destroy($phone->user->id);

// echoes the name just fine, even though the record doesn't exist anymore
echo $phone->user->name;

// manually reload the relationship
$phone->load('user');

// now will show null, since the user was deleted and the relationship was reloaded
var_export($phone->user);