简体   繁体   English

Laravel雄辩模型中的字段

[英]Fields in Laravel Eloquent models

I am new to Laravel and Eloquent, so excuse me if this is a totally stupid question. 我是Laravel和Eloquent的新手,如果这是一个完全愚蠢的问题,请原谅。 I have been looking at how to create a model at both the documentation here and 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.) 我一直在寻找如何创建在两个文件的模型在这里也另一个教程这里 (使用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? 这些字段是否被故意省略,PHP仅在打开FETCH_OBJ并使用PDO执行查询时才添加它们? 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? 这样做是否有助于我们了解我们拥有哪些字段,还可以帮助我们了解IDE(例如PHPStorm)弹出正确的自动完成字段?

If they are actually required, what access level do they need to have? 如果确实需要它们,则需要具有什么访问级别?

Thanks. 谢谢。

Column names (fields) are not required in Eloquent models. Eloquent模型中不需要列名(字段)。 As you pointed out, it is only necessary to define the functions which determine the relationships that a model has with others. 如您所指出的,仅需要定义确定模型与其他模型之间的关系的函数。

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). 由于您提到的原因,不必包括它们(Laravel进行select * ,然后将所有返回的行添加到模型对象作为公共属性)。 This is a process dubbed hydration and you can see exactly what is happening by digging into the Laravel source. 这是一个称为水合的过程,通过深入研究Laravel源,您可以确切地看到正在发生的事情。 Here's a summary of what happens: 以下是发生的情况的摘要:

  1. You call (for example), Users::find(123); 您呼叫(例如), Users::find(123);
  2. Illuminate\\Database\\Eloquent\\Model::find() calls Illuminate\\Database\\Eloquent\\Builder::find() Illuminate\\Database\\Eloquent\\Model::find()调用Illuminate\\Database\\Eloquent\\Builder::find()
  3. find() constructs the SELECT * FROM users WHERE id = 123 query and then returns the first result by calling Illuminate\\Database\\Eloquent\\Builder::first() find()构造SELECT * FROM users WHERE id = 123查询,然后通过调用Illuminate\\Database\\Eloquent\\Builder::first()返回第一个结果
  4. first() adds LIMIT 1 by calling Illuminate\\Database\\Query\\Builder::take() first()通过调用Illuminate\\Database\\Query\\Builder::take()添加LIMIT 1
  5. Then first() sets the columns to be retrieved ( * by default) by calling Illuminate\\Database\\Eloquent\\Builder::get() . 然后, first()通过调用Illuminate\\Database\\Eloquent\\Builder::get()设置要检索的列(默认情况下为* Illuminate\\Database\\Eloquent\\Builder::get()
  6. get() returns an Illuminate\\Database\\Eloquent\\Collection by using the return value of Illuminate\\Database\\Eloquent\\Builder::getModels() get()通过使用Illuminate\\Database\\Eloquent\\Builder::getModels()的返回值返回Illuminate\\Database\\Eloquent\\Collection
  7. getModels() actually performs the query and then calls Illuminate\\Database\\Eloquent\\Model::newFromBuilder() for each row returned getModels()实际上执行查询,然后为返回的每一行调用Illuminate\\Database\\Eloquent\\Model::newFromBuilder()
  8. newFromBuilder() creates a new instance of the model and sets the columns (fields) by calling Illuminate\\Database\\Eloquent\\Model::setRawAttributes() newFromBuilder()创建模型的新实例,并通过调用Illuminate\\Database\\Eloquent\\Model::setRawAttributes()设置列(字段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). 由于 setRawAttributes()的性质,完全可以在模型中声明所有列名称(字段)(只要确保它们是公共的即可)。 The convention, though (and for you sanity), is to omit them. 尽管(为了您的理智)惯例是要省略它们。 Such declarations should be left to migration files . 此类声明应留给 迁移文件

After further examination of the source, it is not ok 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() . 这是因为实际的属性值存储在$attributes属性中,然后由魔术方法__get() The trouble here is that by defining the properties beforehand, you will prevent __get() from being called when you access the fields. 这里的问题是,通过预先定义属性,可以防止在访问字段时调用__get() Therefore, this is not an option. 因此,这不是一个选择。

However, there are ways to hint to editors (like PhpStorm) about the existence of properties without explicitly defining them . 但是,有一些方法可以在没有显式定义属性的情况下向编辑者(如PhpStorm)提示有关属性的存在

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM