Laravel 模型:模型属性在哪里?
Laravel models: Where are model properties?
(我来自 Visual Studio + Entity Framework 背景并试图在 Laravel + Eloquent 中找到等效功能)
在 EF 和 Visual Studio 中,我们向我们的应用程序添加一个新模型,并只告诉它我们现有的数据库。然后 EF 可以为我的 table 生成具有列属性 public 的模型。这为我们提供了所有这些 IDE 和编译器的好处,例如 Intellisense、拼写错误检测等
我最近说过探索 VS Code,Laravel 和 Eloquent。浏览所有这些教程和文章后,我不确定这些属性何时以及如何在模型 classes 中生成。我刚刚尝试了 artisan make:model
命令,它确实生成了模型 class,但其中没有任何属性。所以,
- 我应该手写吗? (真的吗?)
- 这些只是 public 变量还是具有 getter/setter 的标准属性(请原谅我的 .NET 心态 :))?
- 是否有 tool/extension 可以检查我的数据库并创建具有列属性的模型?
更新
非常感谢回答我问题的人。另外,我发表的一些评论是由于我对 PHP(奇怪的 IMO)关于成员访问的方法一无所知;我刚刚发现 PHP 不会抱怨不存在的 class 成员,而是动态生成它们(例如 $post->NonExistingMember = SomeValue
运行正常;这甚至不会用大多数其他语言编译我知道)。给我很大的惊喜。我在其他几种语言中使用过 C++、VB、C#、Java,但在其他任何地方都没有看到这种行为。所有这些语言都会立即抛出一个编译时错误,说类似 Type X 的东西不包含名为 Y 的成员。看不出 PHP 的不同方法如何与 OOP 结合在一起。
我发布此问题的实际问题仍未解决。尽管我可以使用 reliese/laravel 为我的数据库生成模型 classes,该工具仍然不会针对 table 列生成 class 成员,所以我没有得到自动完成好处。如果可以(当然是自动完成),我很想听听专家的意见。
更新 2
现在我对 Laravel 环境的了解稍微好一些,我想我应该分享我的经验。请参阅下面我的回答。
- 不幸的是,你需要手写它们,但只有当你需要更新这些属性的值时,检查点 2($fillable array)
- 您需要声明可填充的属性:
例如,数据库 table "posts" 的名为 Post 的模型有 2 列 "title" 和 "body":
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'];
}
在控制器中:
$newPost = new Post;
$newPost->title = 'A new title';
$newPost->body = 'A new body';
$newPost->save(); //only at this point the db is modified
或者如果您 return 数组或 JSON 响应中的属性,您可以隐藏它们(在集合中也会显示隐藏的属性):
protected $hidden = [
'title',
];
您还可以使用 Accessors
在模型中注入新属性
- 我不这么认为,你可以安装一些 Laravel VS Code 插件让你的生活更轻松(例如:Blade snippets)
您可以查看 this article.
实际上您不需要指定属性。这一切都由 laravel 自动完成。当你创建一个模型时,laravel 使用复数(它有一个非常好的系统:post 变成 posts,activity 变成活动,等等)访问 table 的类名。因此,您可以在不设置 $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;
需要自己添加。例如
$fillable = ['firstname', 'email','username'];
$guarded = ['price'];
我使用注释来声明自动完成的所有属性(在 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'];
}
您可以使用类似这样的方法来获取 table 的所有列的列表,然后 paste/format 将该列表添加到您的注释中:
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = N'tenants';
既然我已经花了一些时间在 Laravel、Eloquent 和 PHP 上,我将分享一些东西,希望这些对其他初学者有所帮助。
PHP 是一种动态语言,它的代码是即时编译的(这与 C# 和 VB.NET 不同)。您的模型 classes 不需要显式定义成员 accessible/assignable,因此只要它们扩展 Model
([=53= 中的内置 class ] Eloquent),您可以将值分配给与基础数据库 table 列同名的不存在的成员,并且 Eloquent 会为您将其存储在数据库中。因此,例如,如果您的数据库中有一个 posts
table,其中有一个名为 body
的列,您可以编写以下代码在您的数据库中创建一个新记录:
$p = new Post;
$p->body = 'Some stuff';
$p->save();
当然你需要在你的项目中有一个从Model
扩展的class Post
但是你不需要在里面定义一个成员body
class。对于来自 .NET 世界的人来说,这听起来很奇怪,但这就是动态语言的工作方式。
至于自动生成模型,Laravel 包含可以为您生成模型的内置命令 (php artisan make:model
)。
最后,对于智能感知和自动完成,请使用 Laravel 本身使用的相同工具,即 DocBlocks。这些是 PHP 中的特殊类型的注释,您可以使用它们来记录您的代码元素。因此,您可以将 DocBlock 添加到包含 属性 名称和类型的所有模型 classes。对每个人来说幸运的是,VS Code 中有一个非常简洁的扩展可以自动为您完成此操作。使用以下命令安装它:
composer require --dev barryvdh/laravel-ide-helper
现在 运行 以下命令为您的所有模型 class 生成文档块(显然您应该在此之前已经生成了数据库和模型):
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 现在将在模型属性中向您显示 table 字段名称,如下所示(查看智能感知如何在我们键入 na...
时从我们的 DocBlocks 中调出 name
成员):
请注意,我还在我的 VS Code 中安装了 Intelephense,但我不确定自动完成功能是否需要这样做。
(我来自 Visual Studio + Entity Framework 背景并试图在 Laravel + Eloquent 中找到等效功能)
在 EF 和 Visual Studio 中,我们向我们的应用程序添加一个新模型,并只告诉它我们现有的数据库。然后 EF 可以为我的 table 生成具有列属性 public 的模型。这为我们提供了所有这些 IDE 和编译器的好处,例如 Intellisense、拼写错误检测等
我最近说过探索 VS Code,Laravel 和 Eloquent。浏览所有这些教程和文章后,我不确定这些属性何时以及如何在模型 classes 中生成。我刚刚尝试了 artisan make:model
命令,它确实生成了模型 class,但其中没有任何属性。所以,
- 我应该手写吗? (真的吗?)
- 这些只是 public 变量还是具有 getter/setter 的标准属性(请原谅我的 .NET 心态 :))?
- 是否有 tool/extension 可以检查我的数据库并创建具有列属性的模型?
更新
非常感谢回答我问题的人。另外,我发表的一些评论是由于我对 PHP(奇怪的 IMO)关于成员访问的方法一无所知;我刚刚发现 PHP 不会抱怨不存在的 class 成员,而是动态生成它们(例如 $post->NonExistingMember = SomeValue
运行正常;这甚至不会用大多数其他语言编译我知道)。给我很大的惊喜。我在其他几种语言中使用过 C++、VB、C#、Java,但在其他任何地方都没有看到这种行为。所有这些语言都会立即抛出一个编译时错误,说类似 Type X 的东西不包含名为 Y 的成员。看不出 PHP 的不同方法如何与 OOP 结合在一起。
我发布此问题的实际问题仍未解决。尽管我可以使用 reliese/laravel 为我的数据库生成模型 classes,该工具仍然不会针对 table 列生成 class 成员,所以我没有得到自动完成好处。如果可以(当然是自动完成),我很想听听专家的意见。
更新 2
现在我对 Laravel 环境的了解稍微好一些,我想我应该分享我的经验。请参阅下面我的回答。
- 不幸的是,你需要手写它们,但只有当你需要更新这些属性的值时,检查点 2($fillable array)
- 您需要声明可填充的属性:
例如,数据库 table "posts" 的名为 Post 的模型有 2 列 "title" 和 "body":
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'];
}
在控制器中:
$newPost = new Post;
$newPost->title = 'A new title';
$newPost->body = 'A new body';
$newPost->save(); //only at this point the db is modified
或者如果您 return 数组或 JSON 响应中的属性,您可以隐藏它们(在集合中也会显示隐藏的属性):
protected $hidden = [
'title',
];
您还可以使用 Accessors
在模型中注入新属性- 我不这么认为,你可以安装一些 Laravel VS Code 插件让你的生活更轻松(例如:Blade snippets) 您可以查看 this article.
实际上您不需要指定属性。这一切都由 laravel 自动完成。当你创建一个模型时,laravel 使用复数(它有一个非常好的系统:post 变成 posts,activity 变成活动,等等)访问 table 的类名。因此,您可以在不设置 $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;
需要自己添加。例如
$fillable = ['firstname', 'email','username'];
$guarded = ['price'];
我使用注释来声明自动完成的所有属性(在 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'];
}
您可以使用类似这样的方法来获取 table 的所有列的列表,然后 paste/format 将该列表添加到您的注释中:
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = N'tenants';
既然我已经花了一些时间在 Laravel、Eloquent 和 PHP 上,我将分享一些东西,希望这些对其他初学者有所帮助。
PHP 是一种动态语言,它的代码是即时编译的(这与 C# 和 VB.NET 不同)。您的模型 classes 不需要显式定义成员 accessible/assignable,因此只要它们扩展 Model
([=53= 中的内置 class ] Eloquent),您可以将值分配给与基础数据库 table 列同名的不存在的成员,并且 Eloquent 会为您将其存储在数据库中。因此,例如,如果您的数据库中有一个 posts
table,其中有一个名为 body
的列,您可以编写以下代码在您的数据库中创建一个新记录:
$p = new Post;
$p->body = 'Some stuff';
$p->save();
当然你需要在你的项目中有一个从Model
扩展的class Post
但是你不需要在里面定义一个成员body
class。对于来自 .NET 世界的人来说,这听起来很奇怪,但这就是动态语言的工作方式。
至于自动生成模型,Laravel 包含可以为您生成模型的内置命令 (php artisan make:model
)。
最后,对于智能感知和自动完成,请使用 Laravel 本身使用的相同工具,即 DocBlocks。这些是 PHP 中的特殊类型的注释,您可以使用它们来记录您的代码元素。因此,您可以将 DocBlock 添加到包含 属性 名称和类型的所有模型 classes。对每个人来说幸运的是,VS Code 中有一个非常简洁的扩展可以自动为您完成此操作。使用以下命令安装它:
composer require --dev barryvdh/laravel-ide-helper
现在 运行 以下命令为您的所有模型 class 生成文档块(显然您应该在此之前已经生成了数据库和模型):
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 现在将在模型属性中向您显示 table 字段名称,如下所示(查看智能感知如何在我们键入 na...
时从我们的 DocBlocks 中调出 name
成员):