Laravel模型:模型属性在哪里?

时间:2018-08-08 11:30:53

标签: php laravel orm model eloquent

(我来自Visual Studio + Entity Framework背景,并试图在Laravel + Eloquent中找到等效的功能)

在EF和Visual Studio中,我们向应用程序添加了一个新模型,并仅向其介绍了我们现有的数据库。然后,EF可以为我的表生成具有列的公共属性的模型。这为我们提供了所有这些IDE和编译器优势,例如Intellisense,拼写错误检测等。

我最近说过要探索VS Code,Laravel和Eloquent。在所有这些教程和文章中,我不确定何时以及如何在模型类中生成这些属性。我刚刚尝试过artisan make:model命令,它确实生成了模型类,但是其中没有属性。所以,

  1. 我应该手写吗? (真的吗?)
  2. 这些将只是具有getter / setter的公共变量或标准属性(对我的.NET心态请原谅:))
  3. 是否有工具/扩展程序可以检查我的数据库并创建具有其列属性的模型?

更新

对于回答我的问题的人们,非常感谢。加上我发表的一些评论是由于我对PHP的成员访问方式(陌生的IMO)的无知。我只是发现PHP不会抱怨不存在的类成员,而是动态生成它们(例如$post->NonExistingMember = SomeValue运行正常;这甚至无法以我所知道的其他大多数语言进行编译)。给我一个很大的惊喜。我已经在其他几种语言中使用过C ++,VB,C#,Java,但在其他任何地方都没有看到这种行为。所有这些语言都会立即抛出编译时错误,如类型X之类的内容不包含名为Y的成员。无法看到PHP的不同方法如何与OOP结合在一起。

我发布此问题的实际问题仍未解决。尽管我可以使用reliese/laravel为我的数据库生成Model类,但是该工具仍然不会针对表列生成类成员,因此无法获得自动完成的好处。我很想听听专家是否可以做到这一点(当然是自动完成)。

5 个答案:

答案 0 :(得分:5)

现在我已经在Laravel,Eloquent和PHP上度过了一段时间,我将分享一些东西,希望它们对其他初学者有所帮助。

PHP是一种动态语言,其代码是动态编译的(这与C#和VB.NET不同)。您的模型类无需显式定义成员以使其可访问/可分配,因此只要它们扩展Model(Laravel Eloquent中的内置类),您便可以将值分配给具有与基础数据库表列的名称相同,Eloquent会为您将其存储在数据库中。因此,例如,如果您的数据库中有一个posts列的body表,则可以编写以下代码在数据库中创建新记录:

$p = new Post;
$p->body = 'Some stuff';
$p->save();

当然,您需要从Post扩展到项目中的一个类Model,但不需要在该类中定义成员body。对于来自.NET世界的人们来说,这听起来很奇怪,但这就是动态语言的工作原理。

关于自动生成模型,Laravel包含可以为您生成模型的内置命令(php artisan make:model)。

最后,要获得智能和自动完成功能,请使用Laravel本身使用的同一工具,即DocBlocks。这些是PHP中的特殊注释类型,您可以使用这些注释来记录代码元素。因此,您可以将DocBlocks添加到包含属性名称和类型的所有模型类中。幸运的是,对于每个人来说,VS Code中都有一个非常巧妙的扩展,可以自动为您执行此操作。使用以下命令安装它:

composer require --dev barryvdh/laravel-ide-helper

现在运行以下命令来为所有模型类生成DocBlock(显然,您应该已经在此之前生成了数据库和模型):

php artisan ide-helper:models --dir='app'

该扩展名将获取数据库的结构并将DocBlocks注入所有模型,如下所示:

/**
 * App\User
 *
 * @property int $id
 * @property string $name
 * @property \Illuminate\Support\Carbon|null $created_at
 * @property \Illuminate\Support\Carbon|null $updated_at
 * @method static \Illuminate\Database\Eloquent\Builder|\App\User whereCreatedAt($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\User whereId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\User whereName($value)
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Exam whereUpdatedAt($value)
 * @mixin \Eloquent
 */
class User extends Model
{
}

VS Code现在将在模型属性中向您显示表字段名称,如下所示(请参见在键入name时intellisense如何从我们的DocBlocks中唤醒na...成员):

enter image description here请注意,虽然我不确定自动完成功能是否需要使用,但我还在VS Code中安装了Intelephense。

答案 1 :(得分:2)

我使用批注来声明所有用于自动完成的属性(在PHPStorm中有效,不确定其他IDE)。

/**
 * @property $id
 * @property $microsoft_id
 * @property $name
 * @property $qualification
 * @property $company
 */
class ShopTenant extends Model
{
    public $connection = 'shop';
    public $table = 'tenants';
    protected $guarded = ['id'];
}

您可以使用类似的方法来获取表中所有列的列表,然后将该列表粘贴/格式化到您的注释中:

SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = N'tenants';

答案 2 :(得分:0)

  1. 很遗憾,是的,您需要手工编写它们,但仅当需要更新这些属性的值时,才检查点2($ fillable array)
  2. 您需要声明可以填充的属性:

例如,一个名为Post的数据库表“ posts”模型具有两列“ title”和“ body”:

POST

在控制器中:

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{

 //not mandatory to declare the table name, Laravel will find it using reflection if you follow the naming standard
 protected $table = 'posts'; //not mandatory

 protected $fillable = ['title','body'];
}

或者如果您在数组或JSON响应中返回属性,则可以隐藏它们(在Collection中还将显示隐藏的属性):

$newPost = new Post;
$newPost->title = 'A new title';
$newPost->body = 'A new body';
$newPost->save(); //only at this point the db is modified

您还可以使用Accessors

在模型中注入新属性
  1. 我不这么认为,您可以安装一些Laravel VS Code插件以简化生活(例如:刀片片段) 您可以检查this article

答案 3 :(得分:0)

实际上,您不需要指定属性。它全部由laravel自动完成。当您创建模型时,laravel使用类名的复数形式(并且它具有非常好的系统:post变成posts,activity变成activity等)来访问表。因此,您可以使用空模型而无需设置$ table或$ fillable / $ guarded属性。

// use only, if your table name differs from the models classname
$table = 'users_options'; // when you want to name your model 'Vote' but the table is called 'users_options' for instance.

// use fillable and guarded only to specify mass-assignment columns
$fillable = [whatever, ...];
$guarded = [whatever, ...];

您可以随时访问属性:

class Post extends Model
{

}

// would do sth like this: select name from posts where id = 1;
// without specifying anything in the model
$name = Post::find(1)->name;

答案 4 :(得分:0)

您需要自己添加。例如

$fillable = ['firstname', 'email','username'];
$guarded = ['price'];