我已经学习Laravel一个月或更长时间,并且受到了脑部的伤害。 在制作了自己的练习网络应用之后,这就是困扰我的地方:
我看到至少有两种方法可以调用方法/函数。有时他们工作,有时却行不通。为什么?和有什么区别?
return ClubTypes::find($id);
return $this->hasMany()->...
在处理sql时,有时需要放->get()
,有时放->get()
会产生未定义的错误。这是怎么回事?
谢谢!
答案 0 :(得分:0)
1)ClubTypes::find()
这就是外墙。外墙为类提供静态接口。Laravel具有许多预定义的外墙,例如Route,Session,DB等。
ClubType是一个类 ::范围解析运算符,用于调用静态和常量。 find()是静态方法。
2)$this->
这是当前类的引用,并且->(箭头/对象运算符)用于调用对象的方法和属性。
答案 1 :(得分:0)
您的问题包含很多细节,这些细节不是Laravel特有的,而是PHP基础。最重要的是用箭头运算符->
调用的实例方法与用双双点运算符::
调用的静态方法之间的区别。当方法调用相对于类(也称为对象)的实例时,使用实例方法,而静态方法用于与类有关但不特定于实例的方法调用。一个例子:
$dog = new Dog();
$dog->bark(); // only an actual dog can bark
echo Dog::species(); // "Canis lupus familiaris" will be the same species for all dogs
有了这些信息,我们现在可以讨论有关Laravel方法的实际区别。
要执行SQL查询,可以使用模型查询构建器。它提供了一个方便的界面来构建查询。大多数查询构建器方法调用都可以非常轻松地转换为SQL。以下三个语句都相同:
Dog::query(); // model query builder
DB::table('dogs'); // untyped query builder
FROM dogs // SQL
对您而言,最有趣的是第一种查询构建器,因此这是一个更复杂的示例:
Dog::query()
->where('color', 'brown')
->where('size', '>=', 50) // centimeter
->get();
// in SQL
SELECT *
FROM dogs
WHERE color = 'brown' AND size >= 50
方法query()
是Model
基类的静态方法,该方法返回一个新的Illuminate\Database\Eloquent\Builder
对象。有些人喜欢显式地调用query()
,但您也可以省略对其的调用并使用
Dog::where('color', 'brown')
->where('size', '>=', 50) // centimeter
->get();
相反。在这里,Model
基类将使用神奇的__callStatic()
函数将对where()
的方法调用通过隧道传输到新的Illuminate\Database\Eloquent\Builder
对象。基本上,这里只是为了方便起见,而您做对了-这简直就是魔术。
当您在模型上定义关系时,您将创建一个返回类似HasMany
或BelongsTo
之类的函数。这些对象是通过使用$this->hasMany()
或$this->belongsTo()
调用的便捷方法创建的:
public function owner(): BelongsTo
{
$this->belongsTo(Person::class);
}
现在调用此关系(我们假设它在Dog
类中),您有两个选择:
$owner = $dog->owner()->first();
$owner = $dog->owner()->getResults(); // the same as first()
$owner = $dog->owner;
前两行将访问该关系并执行实际的SQL查询。基本上是SELECT * FROM persons WHERE id = :owner_id:
。另一方面,第二行将返回dog对象的属性owner
,该属性可以是关系。如果在对象上没有设置owner
属性,并且Laravel找到了一个名为owner()
的方法(该方法返回了一个关系),Laravel将使用前两行之一加载该关系,并将其存储在owner
属性并返回它。因此,它还是第一个的魔术访问器(+它存储结果)。两者更明确的版本是:
$dog->loadMissing('owner');
$owner = $dog->owner;
get()
和first()
返回许多结果(例如HasMany
)的关系将要求您使用get()
来接收结果。其他仅返回一个结果的关系(例如BelongsTo
)将要求您使用first()
。直接查询模型时(例如Dog::where('color', 'brown')->get()
),您可以同时使用这两种方法,具体取决于要获取的内容。 first()
将为您提供理论结果的第一行,这要求您在查询中使用orderBy()
(以便数据库知道第一行是哪一行)。
使用get()
检索结果列表后,您将拥有类型Illuminate\Database\Eloquent\Collection
的对象,并且无法再使用查询生成器方法。在这里,收集方法是适用的。最好您看看method reference。
有一个陷阱,因为您可以使用Dog::all()
但不能使用Dog::query()->all()
。 all()
方法很特殊,可以转换为Dog::query()->get()
。