Laravel使用Seeder自动填充数据
要查看代码,可以点击
或者转到链接:https://github.com/laravel/framework
Laravel自动填充数据使用的是Seeder类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<?php use Illuminate\Database\Seeder; use Illuminate\Database\Eloquent\Model; class DatabaseSeeder extends Seeder { /** * Run the database seeds. */ public function run() { // } } class MyTableSeeder extends Seeder { public function run() { // } } |
你自定义的Seeder只有一个run函数,里面写你的自动填充步骤
大家会注意到这两个函数
1
2
3
4
5
|
Model::unguard(); //你的填充操作 Model::reguard(); |
曾经对这两个函数非常疑惑,到底是干什么用的,只能推测是一对互为反作用的函数。于是去查了下源代码。
在目录\vendor\laravel\framework\src\Illuminate\Database\Eloquent下的Model.php下定义了这两个函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
/** * Disable all mass assignable restrictions. * * @param bool $state * @return void */ public static function unguard( $state = true) { static :: $unguarded = $state ; } /** * Enable the mass assignment restrictions. * * @return void */ public static function reguard() { static :: $unguarded = false; } |
看Laravel作者的注释可以知道,是对数据填充限制的操作。
所以unguard在前,reguard在后,unguard负责解除自动填充操作限制,reguard负责恢复限制。
在填充操作之前,建议使用模型的成员函数
1 | Model::truncate(); |
这个函数会清空这个模型所对应的数据表,所以请慎重使用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
<?php use Illuminate\Database\Seeder; use Illuminate\Database\Eloquent\Model; class DatabaseSeeder extends Seeder { /** * Run the database seeds. */ public function run() { Model::unguard(); $this ->call( 'PostTableSeeder' ); Model::reguard(); } } class PostTableSeeder extends Seeder { public function run() { App\Post::truncate(); factory(App\Post:: class , 1000)->create(); } } |
这里有读者会问:为什么我们不把填充操作都写在自带的DatabaseSeeder的run函数里呢?
因为我们开发一个完整的系统时,可能要填充的数据表有很多张,不希望每次都要大量修改这个run函数。我们还希望每次填充都能保留下这个填充的过程,所以我们宁愿新写一个类,然后用$this->call()函数来调用。
接下来我们来谈谈factory。
文件目录\database\factories\ModelFactory.php
1
2
3
4
5
6
7
|
$factory ->define(App\Post:: class , function ( $faker ) { return [ 'title' => $faker ->sentence(mt_rand(3, 10)), 'content' => join( "\n\n" , $faker ->paragraphs(mt_rand(3, 6))), 'published_at' => $faker ->dateTimeBetween( '-1 month' , '+3 days' ), ]; }); |
虽然能看懂,但是不知道这个$factory变量是什么?因此去查Factory类找。
在目录\vendor\laravel\framework\src\Illuminate\Database\Eloquent的Factory.php找到源代码
1
2
3
4
5
6
7
8
9
10
11
12
|
/** * Define a class with a given set of attributes. * * @param string $class * @param callable $attributes * @param string $name * @return void */ public function define( $class , callable $attributes , $name = 'default' ) { $this ->definitions[ $class ][ $name ] = $attributes ; } |
1
2
3
4
5
6
7
8
9
10
11
|
/** * Create an instance of the given model and persist it to the database. * * @param string $class * @param array $attributes * @return mixed */ public function create( $class , array $attributes = []) { return $this ->of( $class )->create( $attributes ); } |
开始填充数据,我们还是使用artisan命令行
1 | php artisan db:seed |
这个命令会执行你写在DatabaseSeeder.php里面所有的类的run函数,如果以后项目复杂了,没有必要执行已经执行过的,所以在命令行后面加参数,只要执行某个类的run函数即可
1 | php artisan db:seed --class=你要执行的类名称 |