我刚来Laravel ,口才很好,所以请原谅我这是一个非常愚蠢的问题. 在文档here和另一个教程here(在使用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?

如果实际上需要它们,它们需要具有什么访问级别?

谢谢.

推荐答案

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:

  1. 你打电话(例如)Users::find(123);
  2. Illuminate\Database\Eloquent\Model::find()个电话Illuminate\Database\Eloquent\Builder::find()
  3. find()构造SELECT * FROM users WHERE id = 123查询,然后通过调用Illuminate\Database\Eloquent\Builder::first()返回第一个结果
  4. 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().
  6. get() returns an Illuminate\Database\Eloquent\Collection by using the return value of Illuminate\Database\Eloquent\Builder::getModels()
  7. 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()

为了简化过程,我省略了一些不相关的事情,比如急于加载,但基本上每个查询都是这样.

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.

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(). 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.

However, there are ways to hint to editors (like PhpStorm) about the existence of properties without explicitly defining them.

Laravel相关问答推荐

警告:构建Reaction App(VITE)后无法解码下载的字体警告

laravel如何在Blade 模板中将元素添加到数组

在 Laravel 包中的路由上使用显式或隐式模型绑定

FileViewFinder.php 第 137 行中的 Laravel 5 InvalidArgumentException:未找到视图 [.admin]

Laravel 错误ReflectionException-类 App\Http\Kernel 不存在

如何监控 Laravel 队列是否正在运行?

查询 Laravel Select WhereIn 数组

刚安装 Lumen 并得到 NotFoundHttpException

使用 Laravel 限制多态多对多关系中的相关记录

Laravel 验证 - 输入必须是数组中的项目之一

函数 mcrypt_get_iv_size() 在 Laravel 4 上已弃用

将 Laravel Socialite 与 API 一起使用?

Laravel 随机排序

在 Laravel 容器中覆盖单例

Laravel Eloquent 多态一对一?

配置和测试 Laravel 任务调度

将 Laravel 集合排序为 ID 数组

Laravel 不活动时间设置

Laravel 数据库模式中的 MediumBlob

如何在 Laravel 5 请求类中使用有时规则