目的

实际项目开发中我们经常会用到一些假数据来对数据库进行填充以方便调试程序,原始的做法是手工的一个个在数据创建。Laravel提供了一套更加现代化、非常简单易用的数据填充方案。接下来让我们使用Laravel提供的数据填充来批量生成一批假数据。
假数据的生成分为两个阶段:
1.对要生成假数据的模型指定字段进行赋值- {模型工厂}
2.批量生成假数据模型 - {数据填充}

模型工厂

Laravel默认集成了Faker扩展包,使用该扩展包可以方便我们生成一些假数据。
示例如下:

//使用factory 来创建一个Faker\Generator实例
$faker = Faker\Factory::create();
$faker->name;
$faker->safeEmail;
$faker->date;
$faker->time;

借助Faker和Eloquent模型工厂来为指定模型的每个字段设置随机值。
Laravel生成模型工厂
php artisan make:factory UserFactory
实例UserFactory如下:

<?php

use Faker\Generator as Faker;

/*
|--------------------------------------------------------------------------
| Model Factories
|--------------------------------------------------------------------------
|
| This directory should contain each of the model factory definitions for
| your application. Factories provide a convenient way to generate new
| model instances for testing / seeding your application's database.
|
*/

$factory->define(App\Models\User::class, function (Faker $faker) {
    static $password;

    return [
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'password' => $password ?: $password = bcrypt('secret'),
        'remember_token' => str_random(10),
    ];
});

define定义了一个指定数据模型(如此例子User)的模型工厂。define方法接收两个参数,第一个参数指定的Eloquent模型类,第二个参数为一个闭包函数,该闭包函数接受一个FakerPHP函数库的实例,让我们可以在函数内部使用Faker方法生成假数据。

数据填充

Laravel中我们使用Seeder类来给数据库填充测试数据。所有seeder类在database/seeds,文件名需要按照【驼峰式】来命名,且严格遵循大小写规范。Laravel默认定义了DatabaseSeeder类,可在该类中使用call方法来运行其他的Seeder类,以此控制数据填充的顺序。我们可以使用如下命令生成 UserTableSeeder文件。
$ php artisan make:seeder UserTableSeeder
定义好模型工厂后,在UserTableSeeder中使用factory方法来生成一个使用假数据的用户对象。

<?php
use Illuminate\Database\Seeder;
use App\Models\User;

class UserSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        //
        $user = factory(User::class);
        User::insert($user->makeVisible(['password','remember_token']));

        $user = User::find(1);
        $user->name = 'PS';
        $user->email = 'ps@qq.com';
        $user->password = bcrypt('password');
        $user->save();
    }
}

最后一步 在DatabaseSeeder中调用call方法来指定我们要运行假数据填充的文件。

<?php

use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;

class DatabaseSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        // $this->call(UsersTableSeeder::class);
        Model::unguard();
        $this->call(UserSeeder::class);
        Model::reguard();
    }
}

运行命令重置数据库,执行数据填充

$ php artisan migrate:refresh
$ php artisan db:seed

单独执行某个UserSeeder文件如下:

$ php artisan migrate:refresh
$ php artisan db:seed --class=UserSeeder

一条命令同时完成数据库重置和填充操作:

$ php artisan migrate:refresh --seed