laravel - laravel如何调用方法
问题描述
我现在已经学习 Laravel 一个月或更长时间了,而且脑痛。在制作了我自己的练习网络应用程序之后,这让我很烦恼:
我看到(至少)两种调用方法/函数的方法。有时他们工作,有时他们不工作。为什么?有什么区别?
return ClubTypes::find($id);
return $this->hasMany()->...
而在处理 sql 时,有时我需要放置->get()
有时->get()
会给出未定义的错误.. 那是怎么回事?
谢谢!
解决方案
您的问题包含许多不是 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
or的函数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:
。另一方面,第二行将返回owner
dog 对象的属性,可以是关系。如果对象上没有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()
.
推荐阅读
- javascript - Word 加载项替换当前文档字节
- css - CSS 选择器:“仅在没有父 Y 时选择 X”
- android - 在使用 Retrofit 调用获取 Web 服务请求时。“android.os.TransactionTooLargeException:数据包大小 1575704 字节”
- firebase - Angular 6,Firebase 存储网络图片库
- mysql - 在 MySQL 中选择多于一行的特定值和条件依赖项
- c++ - 在 Windows 和 Clion 上使用 OpenCV
- javascript - jQuery 对话框 - 内部 html 超链接
- python - 使用 selenium python 来自 tradingview 的数据
- excel - 构造一个嵌套的if excel公式
- javascript - 如何修改缩小的 javascript 文件以及随附的源映射?