方法调用之间的区别 $model->relation();和 $model->relation;
Difference between method calls $model->relation(); and $model->relation;
这里有一些基本的understanding/theory,我missing.I不明白这些函数调用之间的区别:
$distributors = $store->distributors();
$distributors = $store->distributors;
$distributors = $store->distributors()->get();
$distributors = $store->distributors->get();
我在这里想要完成的是获取一家商店的经销商列表(多对多关系),他们将每个经销商的啤酒列表放入一个巨大的列表中。
foreach ($distributors as $distributor)
{
$available_beers = array_merge($distributor->beers(), $available_beers);
}
我不知道这是否是执行此操作的最佳方法,而且我无法让它工作。类似于第一个方法列表,不知道需要->$beers
还是->$beers()
更新
感谢所有回答的人!这对我以后的工作有很好的参考作用。我最大的教训是取回集合与取回查询 builder/relationship 对象之间的区别。为了将来找到这个问题的人参考,这是我在我的控制器中设置的:
$store = $this->store->find($id)->first();
$distributors = $store->distributors;
$beers = [];
foreach ($distributors as $distributor){
$beers = array_merge($distributor->beers->lists('name', 'id'), $beers);
}
也许这会有用。
获取方法:
$object->method();
访问属性:
$object->property;
假设商店 class 看起来像这样:
<?php
class Store {
public $distributors;
function __construct($distributors = array()) {
$this->distributors = $distributors;
}
public function distributors() {
return $this->distributors;
}
}
所以区别是:
$store = new Store(array('some guy', 'some other guy'));
$guys = $store->distributors; # accesing the $distributors property
$more = $store->distributors(); # calling the distributors() method.
$distributors = $store->distributors();
方法(函数)的结果
$distributors = $store->distributors;
属性 的值(变量)
$distributors = $store->distributors()->get();
以第一个为例,它是方法的结果,如果方法 return 是一个对象,则这是该对象中 returned 的方法。
$distributors = $store->distributors->get();
如果 属性 是一个对象,那么它会调用其中的一个方法 属性 那是一个对象。
Re ->$beers vs ->$beers()
这是 property/method 的动态名称,具体取决于您的用途。粗略地猜测一下你在做什么,在你的 class 中你将拥有
$this->beers = array('bud','miller','sam');
并且在您使用 $store 对象的代码中,您实际上将进行类似
的操作
$drink_type = 'beers';
$drink_list = $store->$drink_type;
然后 return $this->beers
来自 $store
,与写 $store->beers
;
相同
当您处理与 Eloquent 的关系时,属性 是您的关系的集合 (Illuminate\Database\Eloquent\Collection
) white 该方法是新查询的开始。
假设您的模型如下所示:
class User extends Eloquent {
public function roles()
{
return $this->belongsToMany('Role');
}
}
如果您尝试访问 $user->roles
,Eloquent 将 运行 查询并获取与该用户相关的所有角色,感谢 magic methods 和 return是 Illuminate\Database\Eloquent\Collection
的一个实例。 class 有一个名为 get
的方法,这就是 $user->roles->get()
适合你的原因。
如果您尝试访问该方法 $user->roles()
,您将获得一个查询构建器对象,以便您可以微调您的查询。
$user->roles()->whereIn('role_id', [1, 3, 4])->get();
只有 return 个角色,其中 role_id
是 1
、3
或 4
。
因此,属性 return 是一个完整的查询,它会产生 (Illuminate\Database\Eloquent\Collection
),而该方法允许您自定义查询。
简答
$model->relation()
return 是 关系对象
$model->relation
return是关系
的结果
长答案
$model->relation()
可以解释的很简单。您正在调用您定义关系的实际函数。你的 distributor
可能看起来有点像这样:
public function distributors(){
return $this->hasMany('Distributor');
}
因此,当调用 $store->distributors()
时,您只需获得 $this->hasMany('Distributor')
的 return 值,它是 Illuminate\Database\Eloquent\Relations\HasMany
的一个实例
什么时候用?
如果您想在 运行 之前进一步指定查询,通常会调用关系函数。例如添加一个 where 语句:
$distributors = $store->distributors()->where('priority', '>', 4)->get();
当然你也可以这样做:$store->distributors()->get()
但结果与 $store->distributors
相同。
这让我想到了 动态关系 属性 的解释。
Laravel 在幕后做了一些事情,让您可以直接访问 属性 关系的结果。喜欢:$model->relation
.
这是 Illuminate\Database\Eloquent\Model
中发生的事情
1) 这些属性实际上并不存在。因此,如果您访问 $store->distributors
,呼叫将被代理到 __get()
2) 此方法然后调用 getAttribute
并使用 属性 名称 getAttribute('distributors')
public function __get($key)
{
return $this->getAttribute($key);
}
3) 在 getAttribute
中,它检查关系是否已经加载(存在于 relations
中)。如果不存在并且存在关系方法,它将加载关系 (getRelationshipFromMethod
)
public function getAttribute($key)
{
// code omitted for brevity
if (array_key_exists($key, $this->relations))
{
return $this->relations[$key];
}
$camelKey = camel_case($key);
if (method_exists($this, $camelKey))
{
return $this->getRelationshipFromMethod($key, $camelKey);
}
}
4) 最后 Laravel 在关系上调用 getResults()
,然后在查询构建器实例上产生 get()
。 (这给出了与 $model->relation()->get()
.
相同的结果
您问题的直接答案:
$store->distributors()
将 return 实际关系对象 (\Illuminate\Database\Eloquent\Relations\BelongsToMany)。
$store->distributors
将是一个包含关系查询结果的集合 (\Illuminate\Database\Eloquent\Collection)。
$store->distributors()->get()
将是一个包含关系查询结果的集合 (\Illuminate\Database\Eloquent\Collection)。
$store->distributors->get()
应该 return 一个错误,因为您在 Collection 对象上调用 get()
并且第一个参数不是可选的。如果不是错误,它至少应该 return null.
更多信息:
给定以下模型:
class Store extends Eloquent {
public function distributors() {
return $this->belongsToMany('Distributor');
}
}
调用关系方法 ($store->distributors()
) 将 return 给你关系 (\Illuminate\Database\Eloquent\Relations\BelongsToMany) 对象。这基本上是一个您可以继续修改的查询对象,但您仍然需要调用某种类型的方法来获取结果(例如 get()
、first()
等)。
但是,访问关系属性 ($store->distributors
) 将 return 给您一个包含执行关系查询结果的集合 (\Illuminate\Database\Eloquent\Collection) 对象。
默认情况下,关系属性会在第一次访问时创建并分配一个值(称为 "lazy loading")。因此,您第一次访问 $store->distributors
时,它在后台执行关系查询,将结果存储在 $store->distributors
属性中,然后 return 获取这些结果。但是,它只执行一次。下次您访问 $store->distributors
时,该属性已包含数据,因此这就是您正在访问的内容。
为了说明这一点:
// the following two statements will run the query twice
$r1 = $store->distributors()->get();
$r2 = $store->distributors()->get();
// the following two statements will run the query once.
// the first statement runs the query, populates $store->distributors, and assigns the variable
// the second statement just accesses the data now stored in $store->distributors
$r3 = $store->distributors;
$r4 = $store->distributors;
// at the end, $r1 == $r2 == $r3 == $r4
关系也可以 "eager" 加载,在查询中使用 with()
方法。这样做是为了减轻延迟加载可能需要的所有额外查询(称为 n+1 问题)。您可以阅读更多相关信息 here。
主要区别在于:
$distributors = $store->distributors()
return 关系对象的实例,如 Illuminate\Database\Eloquent\Relations\BelongsToMany
。您可以在调用此后使用其他条件,例如where
。
$store->distributors
return 集合实例 Illuminate/Database/Eloquent/Collection
。 Laravel 在后台调用魔术方法 __get
。它将return一个查询关系的结果
这里有一些基本的understanding/theory,我missing.I不明白这些函数调用之间的区别:
$distributors = $store->distributors();
$distributors = $store->distributors;
$distributors = $store->distributors()->get();
$distributors = $store->distributors->get();
我在这里想要完成的是获取一家商店的经销商列表(多对多关系),他们将每个经销商的啤酒列表放入一个巨大的列表中。
foreach ($distributors as $distributor)
{
$available_beers = array_merge($distributor->beers(), $available_beers);
}
我不知道这是否是执行此操作的最佳方法,而且我无法让它工作。类似于第一个方法列表,不知道需要->$beers
还是->$beers()
更新
感谢所有回答的人!这对我以后的工作有很好的参考作用。我最大的教训是取回集合与取回查询 builder/relationship 对象之间的区别。为了将来找到这个问题的人参考,这是我在我的控制器中设置的:
$store = $this->store->find($id)->first();
$distributors = $store->distributors;
$beers = [];
foreach ($distributors as $distributor){
$beers = array_merge($distributor->beers->lists('name', 'id'), $beers);
}
也许这会有用。
获取方法:
$object->method();
访问属性:
$object->property;
假设商店 class 看起来像这样:
<?php
class Store {
public $distributors;
function __construct($distributors = array()) {
$this->distributors = $distributors;
}
public function distributors() {
return $this->distributors;
}
}
所以区别是:
$store = new Store(array('some guy', 'some other guy'));
$guys = $store->distributors; # accesing the $distributors property
$more = $store->distributors(); # calling the distributors() method.
$distributors = $store->distributors();
方法(函数)的结果
$distributors = $store->distributors;
属性 的值(变量)
$distributors = $store->distributors()->get();
以第一个为例,它是方法的结果,如果方法 return 是一个对象,则这是该对象中 returned 的方法。
$distributors = $store->distributors->get();
如果 属性 是一个对象,那么它会调用其中的一个方法 属性 那是一个对象。
Re ->$beers vs ->$beers()
这是 property/method 的动态名称,具体取决于您的用途。粗略地猜测一下你在做什么,在你的 class 中你将拥有
$this->beers = array('bud','miller','sam');
并且在您使用 $store 对象的代码中,您实际上将进行类似
的操作$drink_type = 'beers';
$drink_list = $store->$drink_type;
然后 return $this->beers
来自 $store
,与写 $store->beers
;
当您处理与 Eloquent 的关系时,属性 是您的关系的集合 (Illuminate\Database\Eloquent\Collection
) white 该方法是新查询的开始。
假设您的模型如下所示:
class User extends Eloquent {
public function roles()
{
return $this->belongsToMany('Role');
}
}
如果您尝试访问 $user->roles
,Eloquent 将 运行 查询并获取与该用户相关的所有角色,感谢 magic methods 和 return是 Illuminate\Database\Eloquent\Collection
的一个实例。 class 有一个名为 get
的方法,这就是 $user->roles->get()
适合你的原因。
如果您尝试访问该方法 $user->roles()
,您将获得一个查询构建器对象,以便您可以微调您的查询。
$user->roles()->whereIn('role_id', [1, 3, 4])->get();
只有 return 个角色,其中 role_id
是 1
、3
或 4
。
因此,属性 return 是一个完整的查询,它会产生 (Illuminate\Database\Eloquent\Collection
),而该方法允许您自定义查询。
简答
$model->relation()
return 是 关系对象
$model->relation
return是关系
长答案
$model->relation()
可以解释的很简单。您正在调用您定义关系的实际函数。你的 distributor
可能看起来有点像这样:
public function distributors(){
return $this->hasMany('Distributor');
}
因此,当调用 $store->distributors()
时,您只需获得 $this->hasMany('Distributor')
的 return 值,它是 Illuminate\Database\Eloquent\Relations\HasMany
什么时候用?
如果您想在 运行 之前进一步指定查询,通常会调用关系函数。例如添加一个 where 语句:
$distributors = $store->distributors()->where('priority', '>', 4)->get();
当然你也可以这样做:$store->distributors()->get()
但结果与 $store->distributors
相同。
这让我想到了 动态关系 属性 的解释。
Laravel 在幕后做了一些事情,让您可以直接访问 属性 关系的结果。喜欢:$model->relation
.
这是 Illuminate\Database\Eloquent\Model
1) 这些属性实际上并不存在。因此,如果您访问 $store->distributors
,呼叫将被代理到 __get()
2) 此方法然后调用 getAttribute
并使用 属性 名称 getAttribute('distributors')
public function __get($key)
{
return $this->getAttribute($key);
}
3) 在 getAttribute
中,它检查关系是否已经加载(存在于 relations
中)。如果不存在并且存在关系方法,它将加载关系 (getRelationshipFromMethod
)
public function getAttribute($key)
{
// code omitted for brevity
if (array_key_exists($key, $this->relations))
{
return $this->relations[$key];
}
$camelKey = camel_case($key);
if (method_exists($this, $camelKey))
{
return $this->getRelationshipFromMethod($key, $camelKey);
}
}
4) 最后 Laravel 在关系上调用 getResults()
,然后在查询构建器实例上产生 get()
。 (这给出了与 $model->relation()->get()
.
您问题的直接答案:
$store->distributors()
将 return 实际关系对象 (\Illuminate\Database\Eloquent\Relations\BelongsToMany)。$store->distributors
将是一个包含关系查询结果的集合 (\Illuminate\Database\Eloquent\Collection)。$store->distributors()->get()
将是一个包含关系查询结果的集合 (\Illuminate\Database\Eloquent\Collection)。$store->distributors->get()
应该 return 一个错误,因为您在 Collection 对象上调用get()
并且第一个参数不是可选的。如果不是错误,它至少应该 return null.
更多信息:
给定以下模型:
class Store extends Eloquent {
public function distributors() {
return $this->belongsToMany('Distributor');
}
}
调用关系方法 ($store->distributors()
) 将 return 给你关系 (\Illuminate\Database\Eloquent\Relations\BelongsToMany) 对象。这基本上是一个您可以继续修改的查询对象,但您仍然需要调用某种类型的方法来获取结果(例如 get()
、first()
等)。
但是,访问关系属性 ($store->distributors
) 将 return 给您一个包含执行关系查询结果的集合 (\Illuminate\Database\Eloquent\Collection) 对象。
默认情况下,关系属性会在第一次访问时创建并分配一个值(称为 "lazy loading")。因此,您第一次访问 $store->distributors
时,它在后台执行关系查询,将结果存储在 $store->distributors
属性中,然后 return 获取这些结果。但是,它只执行一次。下次您访问 $store->distributors
时,该属性已包含数据,因此这就是您正在访问的内容。
为了说明这一点:
// the following two statements will run the query twice
$r1 = $store->distributors()->get();
$r2 = $store->distributors()->get();
// the following two statements will run the query once.
// the first statement runs the query, populates $store->distributors, and assigns the variable
// the second statement just accesses the data now stored in $store->distributors
$r3 = $store->distributors;
$r4 = $store->distributors;
// at the end, $r1 == $r2 == $r3 == $r4
关系也可以 "eager" 加载,在查询中使用 with()
方法。这样做是为了减轻延迟加载可能需要的所有额外查询(称为 n+1 问题)。您可以阅读更多相关信息 here。
主要区别在于:
$distributors = $store->distributors()
return 关系对象的实例,如Illuminate\Database\Eloquent\Relations\BelongsToMany
。您可以在调用此后使用其他条件,例如where
。$store->distributors
return 集合实例Illuminate/Database/Eloquent/Collection
。 Laravel 在后台调用魔术方法__get
。它将return一个查询关系的结果