Laravel 数据库 - 数据填充

1.应用场景

快速填充数据, 帮助开发和测试.

2.学习/操作

环境:

Windows10 64位 专业版

laravel 5.8 / 5.7 

 

1. 生成迁移文件/并且回滚操作正常

见: https://blog.csdn.net/william_n/article/details/103612764

php artisan migrate

php artisan migrate:rollback

php artisan migrate:reset

 

2. 生成工厂模型文件, 并修改调整 [数据库填充器使用模型工厂生成随机数据]

php artisan make:factory PostFactory --model=Models/Post
 

3. 生成数据填充相关设置文件, 并修改调整

php artisan make:seeder PostsTableSeeder

 

结果如下:

Laravel 数据库 - 数据填充_第1张图片

 

4. 执行脚本命令, 

php artisan db:seed 

或者

在执行迁移命令, 生成数据表时, 带上参数即可

php artisan  migrate --seed

Laravel 数据库 - 数据填充_第2张图片

数据库:

Laravel 数据库 - 数据填充_第3张图片

 

后续整理

...

3.问题

1.执行数据填充明命令出现报错

命令: $ php artisan db:seed

报错信息: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '' for key 'posts_slug_unique' (SQL: insert into `posts` (`title`, `content`, `published_at`, `updated_at`, `created_at`) values (Temporibus praesentium id volu ....

 

错误原因:

Laravel 数据库 - 数据填充_第4张图片

Laravel 数据库 - 数据填充_第5张图片

因为slug列设置唯一索引, 则该列数据值必须是唯一的, 不能重复, 但是迁移文件中并没有为该列设置值, 那就意味着都为空, 

MySQL 唯一索引允许为null, 但是只能有一个为null, 所以laravel会提示没有为该唯一索引列设置默认值.

 

但是为唯一索引列设置默认值,还会出现违反完整性约束, 所以需要在填充数据时, 要使用不同的数据去填充.

可以添加: //database/factories/PostFactory.php文

'slug' => $faker->slug(),

 

2. 数据填充时, unguard / reguard 这二个方法怎么理解?

database/seeds/DatabaseSeeder.php

Laravel 数据库 - 数据填充_第6张图片

或者:

Model::unguard();

$this->call(UsersTableSeeder::class);

Model::reguard();

 

Model::unguard() 用于取消批量赋值白名单、黑名单属性校验, 

Model::reguard() 用于恢复校验。

 

简单来说,是临时取消批量赋值(mass assignment)保护,因为此时可能需要批量对 is_admin 等敏感属性进行赋值,而为了安全这是不允许的。

详细解答: https://learnku.com/laravel/t/9998/how-do-the-two-methods-of-unguard-reguard-understand

 

3. 什么是 mass assignment

laravel 文档中经常会提到 mass assignment,我简单翻译为批量赋值,其实质是为了防止用户恶意注入数据,保护数据的安全。//[之前使用的php原生框架就自行使用了批量赋值,想在想来有恶意注入数据的嫌疑]

 

举例来说,你的用户表有 users 里有 is_admin 属性,标识该用户是否为管理员,正常情况下你当然不希望用户自己设置此属性。但如果你包含了如下代码:

$user = new User(input::all());

 

则用户可能恶意构造数据,同时提交了 name、password、is_admin 等字段,从而将自己设置为管理员,这就带来了安全问题。

2. 解决方案

于是,laravel 提供了两种解决方案。

其一:即设置 fillable 属性,列入针对上述问题,设置

protected $fillable = ['name', 'password', 'email'];

 

此时即使用户提交了 is_admin 属性也会被忽略。那么我们如何才能设置此属性呢?单独赋值,即

$user->is_admin = true; 
$user->save();

 

 

这种方式教程里面也有涉及。

其二:设置 guarded 属性

protected $guarded = ['is_admin'];

 

注意,guarded 属性是仅保护这个属性,其余所有属性均可批量赋值,与 fillable 刚好相反,两种方式任选一种即可

laravel 参考文档:mass assignment

3. 为什么要有 model::unguard ()

至此,为什么要 unguard 然后 guard 应该就十分清楚了,从方法名很容易就看出来。

为了批量填充数据,当然要暂时性关闭安全保护,填充完毕后重新打开保护。

当然,此处还有一点问题,就是我在 laravel 文档里并没有搜到这两个方法...

如果你看到了欢迎补充链接.

4.填充文件中,使用随机字符串进行进行填充

laravel 7.x 

database\seeds\UsersTableSeeder.php

直接使用str_random(); //会出现报错

解决办法:

use Illuminate\Support\Str;

...

'name' => Str::random(10),

Laravel 数据库 - 数据填充_第7张图片

 

 

 

 

后续补充

...

4.参考

https://xueyuanjun.com/books/laravel-docs-5_8/chapter/database  //数据库操作

https://xueyuanjun.com/post/9581  //数据填充

https://xueyuanjun.com/post/2976  //填充数据

https://learnku.com/laravel/t/9998/how-do-the-two-methods-of-unguard-reguard-understand  //unguard / reguard 这二个方法怎么理解?

https://laravel.com/docs/6.x/eloquent#mass-assignment //Eloquent: Getting Started

后续补充

...

你可能感兴趣的:(LARAVEL,数据库-DATABASE,数据填充,factory,seeder)