(我来自Visual Studio + Entity Framework背景,并试图在Laravel + Eloquent中找到等效的功能)
在EF和Visual Studio中,我们向应用程序添加了一个新模型,并仅向其介绍了我们现有的数据库。然后,EF可以为我的表生成具有列的公共属性的模型。这为我们提供了所有这些IDE和编译器优势,例如Intellisense,拼写错误检测等。
我最近说过要探索VS Code,Laravel和Eloquent。在所有这些教程和文章中,我不确定何时以及如何在模型类中生成这些属性。我刚刚尝试过artisan make:model
命令,它确实生成了模型类,但是其中没有属性。所以,
对于回答我的问题的人们,非常感谢。加上我发表的一些评论是由于我对PHP的成员访问方式(陌生的IMO)的无知。我只是发现PHP不会抱怨不存在的类成员,而是动态生成它们(例如$post->NonExistingMember = SomeValue
运行正常;这甚至无法以我所知道的其他大多数语言进行编译)。给我一个很大的惊喜。我已经在其他几种语言中使用过C ++,VB,C#,Java,但在其他任何地方都没有看到这种行为。所有这些语言都会立即抛出编译时错误,如类型X之类的内容不包含名为Y的成员。无法看到PHP的不同方法如何与OOP结合在一起。
我发布此问题的实际问题仍未解决。尽管我可以使用reliese/laravel为我的数据库生成Model类,但是该工具仍然不会针对表列生成类成员,因此无法获得自动完成的好处。我很想听听专家是否可以做到这一点(当然是自动完成)。
答案 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...
成员):
答案 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)
例如,一个名为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
在模型中注入新属性答案 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'];