Laravel Eloquent 模型中的字段
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26111283/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Fields in Laravel Eloquent models
提问by jbx
I am new to Laravel and Eloquent, so excuse me if this is a totally stupid question. I have been looking at how to create a model at both the documentation hereand also another tutorial here(in the Creating Models using Eloquent ORM section) and I've noticed that the actual fields of the table are never mentioned, unless there is something specific about them (like having a relationship with another table, or not requiring mass assignment, or if they need to be hidden from JSON output etc.)
我是 Laravel 和 Eloquent 的新手,所以如果这是一个完全愚蠢的问题,请原谅我。我一直在寻找如何创建在两个文件的模型在这里也另一个教程这里(使用ORM口才节中创建模型),我已经注意到,该表的实际字段都未曾提及,除非有什么特定于它们(比如与另一个表有关系,或者不需要批量赋值,或者如果它们需要从 JSON 输出中隐藏等等)
Are these fields being omitted on purpose and PHP just adds them when it performs the query using PDO with FETCH_OBJ
turned on?
If yes why is it that we do not explicitly put the fields in the model? Doesn't it help us to know what fields we have, and also IDEs such as PHPStorm to pop up the right auto-complete fields?
这些字段是否被故意省略,而 PHP 只是在使用 PDO 执行查询时添加它们并FETCH_OBJ
打开?如果是,为什么我们没有明确地将字段放入模型中?是否有助于我们了解我们拥有哪些字段,以及诸如 PHPStorm 之类的 IDE 来弹出正确的自动完成字段?
If they are actually required, what access level do they need to have?
如果确实需要它们,它们需要具有什么访问级别?
Thanks.
谢谢。
回答by Bailey Parker
Column names (fields) are not required in Eloquent models. As you pointed out, it is only necessary to define the functions which determine the relationships that a model has with others.
Eloquent 模型中不需要列名(字段)。正如您所指出的,只需定义确定模型与其他模型之间关系的函数即可。
It isn't necessary to include them, because of the reason you mentioned (Laravel does a select *
and then adds all of the returned rows to the model object as public properties). This is a process dubbed hydration and you can see exactly what is happening by digging into the Laravel source. Here's a summary of what happens:
由于您提到的原因,没有必要包含它们(Laravel 执行 aselect *
然后将所有返回的行作为公共属性添加到模型对象中)。这是一个称为“水化”的过程,您可以通过深入了解 Laravel 源来准确了解发生了什么。以下是所发生情况的摘要:
- You call (for example),
Users::find(123);
Illuminate\Database\Eloquent\Model::find()
callsIlluminate\Database\Eloquent\Builder::find()
find()
constructs theSELECT * FROM users WHERE id = 123
query and then returns the first result by callingIlluminate\Database\Eloquent\Builder::first()
first()
addsLIMIT 1
by callingIlluminate\Database\Query\Builder::take()
- Then
first()
sets the columns to be retrieved (*
by default) by callingIlluminate\Database\Eloquent\Builder::get()
. get()
returns anIlluminate\Database\Eloquent\Collection
by using the return value ofIlluminate\Database\Eloquent\Builder::getModels()
getModels()
actually performs the query and then callsIlluminate\Database\Eloquent\Model::newFromBuilder()
for each row returnednewFromBuilder()
creates a new instance of the model and sets the columns (fields) by callingIlluminate\Database\Eloquent\Model::setRawAttributes()
- 你打电话(例如),
Users::find(123);
Illuminate\Database\Eloquent\Model::find()
电话Illuminate\Database\Eloquent\Builder::find()
find()
构造SELECT * FROM users WHERE id = 123
查询,然后通过调用返回第一个结果Illuminate\Database\Eloquent\Builder::first()
first()
LIMIT 1
通过调用添加Illuminate\Database\Query\Builder::take()
- 然后通过调用
first()
设置要检索的列(*
默认情况下)Illuminate\Database\Eloquent\Builder::get()
。 get()
Illuminate\Database\Eloquent\Collection
通过使用的返回值返回一个Illuminate\Database\Eloquent\Builder::getModels()
getModels()
实际执行查询,然后调用Illuminate\Database\Eloquent\Model::newFromBuilder()
返回的每一行newFromBuilder()
创建模型的新实例并通过调用设置列(字段)Illuminate\Database\Eloquent\Model::setRawAttributes()
I've omitted some unrelated things such as eager loading to simplify the process, but this is basically what happens for each query.
我省略了一些不相关的事情,例如急切加载以简化过程,但这基本上是每个查询都会发生的事情。
You make a good point that knowing the fields beforehand can be helpful for autocompletion. Because of the nature of setRawAttributes()
it is perfectly OK to declare all column names (fields) in your model (just make sure they are public). The convention, though (and for you sanity), is to omit them. Such declarations should be left to migration files.
您提出了一个很好的观点,即事先了解字段有助于自动完成。由于setRawAttributes()
在模型中声明所有列名(字段)的性质是完全可以的(只需确保它们是公共的)。尽管如此(为了你的理智),惯例是省略它们。此类声明应留给迁移文件。
After further examination of the source, it is notok to declare the fields beforehand. This is because the actual attribute values are stored in an $attributes
property and then accessed by the magic method __get()
. The trouble here is that by defining the properties beforehand, you will prevent __get()
from being called when you access the fields. Therefore, this is not an option.
进一步检查来源后,事先声明字段是不行的。这是因为实际的属性值存储在$attributes
属性中,然后由魔法方法访问__get()
。这里的麻烦在于,通过预先定义属性,您将防止__get()
在访问字段时被调用。因此,这不是一个选项。
However, there are ways to hint to editors (like PhpStorm) about the existence of properties without explicitly defining them.
回答by ibamboo
There is another way to make phpstorm to auto-complete column name and avoid warning.
还有另一种方法可以让 phpstorm 自动完成列名并避免警告。
/**
* @property string $title Title of article
*/
class Article extends Eloquent