首页 > 解决方案 > laravel如何调用方法

问题描述

我现在已经学习 Laravel 一个月或更长时间了,而且脑痛。在制作了我自己的练习网络应用程序之后,这让我很烦恼:

我看到(至少)两种调用方法/函数的方法。有时他们工作,有时他们不工作。为什么?有什么区别?

return ClubTypes::find($id);
return $this->hasMany()->...

而在处理 sql 时,有时我需要放置->get()有时->get()会给出未定义的错误.. 那是怎么回事?

谢谢!

标签: laravelclassoopeloquent

解决方案


您的问题包含许多不是 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对象。它基本上只是为了方便而存在的,而且你做对了——它真的很神奇。

关系

当您在模型上定义关系时,您会创建一个返回类似HasManyor的函数BelongsTo。这些对象是通过使用$this->hasMany()or调用的便捷方法创建的$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:。另一方面,第二行将返回ownerdog 对象的属性,可以是关系。如果对象上没有owner设置属性,并且 Laravel 找到一个调用的方法owner()(并且该方法返回一个关系),Laravel 将使用前两行之一加载此关系,将其存储在owner属性下并返回它。所以它又是第一个的魔法访问器(+ 它存储结果)。两者的更明确的版本是:

$dog->loadMissing('owner');
$owner = $dog->owner;

get()first()

返回许多结果的关系(例如HasMany)将要求您使用get()来接收结果。仅返回一个结果的其他关系(例如BelongsTo)将要求您使用first(). 直接查询模型时(如Dog::where('color', 'brown')->get()),您可以同时使用两者,具体取决于您想要获得的内容。first()会给你理论结果的第一行,这需要你orderBy()在查询上使用an(以便数据库知道第一行是哪一行)。

使用 检索结果列表后get(),您就拥有了一个类型的对象,Illuminate\Database\Eloquent\Collection并且您不能再使用查询构建器方法。在这里,收集方法是适用的。最好看一下方法参考

有一个陷阱,您可以使用Dog::all()但不能使用Dog::query()->all(). 方法比较特殊,all()可以翻译成Dog::query()->get().


推荐阅读