Laravel 中 Factory 与 Seeder 有什么区别

Laravel 的 Factory 负责按模型批量生成假数据(借助 Faker),Seeder 负责编排数据填充流程。Seeder 管"填什么、按什么顺序",Factory 管"每条数据长什么样",两者常配合使用。

最佳实践
应用程序模块协作插画

直接回答:Factory 是数据生成器——定义某个模型的假数据模板并可批量造数;Seeder 是填充脚本——决定向数据库写入哪些数据、以什么顺序执行。 实际开发中通常在 Seeder 里调用 Factory:Seeder 编排流程,Factory 产出数据。

Factory:定义"数据长什么样"

以下是已有 Laravel 项目中的类体片段,省略 namespace/import;需补齐 Factory、Seeder、DB、User 的实际命名空间,模型还需 HasFactory 和示例关联。固定测试密码与 Faker 数据仅限隔离测试数据库。

Factory 绑定一个模型,用 Faker 生成随机但格式合理的字段值:

// database/factories/UserFactory.php
class UserFactory extends Factory
{
    public function definition(): array
    {
        return [
            'name' => fake()->name(),
            'email' => fake()->unique()->safeEmail(),
            'password' => bcrypt('password'),
        ];
    }
}

使用:

User::factory()->count(50)->create();          // 造 50 个用户
User::factory()->hasPosts(3)->create();        // 顺便给每个用户造 3 篇文章(关联关系)
User::factory()->make();                       // 只生成模型实例,不落库(常用于单测)

Factory 的强项:

  • 批量生成:一条命令造任意数量
  • 处理关联:hasPosts()、for(User::factory()) 等轻松构造关联数据
  • 状态变换:->state(['role' => 'admin']) 快速得到特定形态的数据
  • 测试中复用:单元测试里 ->make() 不落库,又快又干净

Seeder:定义"怎么填"

Seeder 类放在 database/seeders/,入口是 DatabaseSeeder,通过 call() 编排执行顺序:

class DatabaseSeeder extends Seeder
{
    public function run(): void
    {
        // 直接写死基础数据
        DB::table('roles')->insert([
            ['name' => 'admin'],
            ['name' => 'user'],
        ]);

        // 调用 Factory 造测试数据
        User::factory()->count(50)->hasPosts(1)->create();

        // 编排其他 Seeder
        $this->call([
            ProductSeeder::class,
            OrderSeeder::class,
        ]);
    }
}

执行:

php artisan db:seed                     # 跑 DatabaseSeeder
php artisan db:seed --class=ProductSeeder
# 破坏性命令:删除目标连接全部数据表,仅限已确认可丢弃的测试数据库
php artisan migrate:fresh --seed

分工对照

维度 Factory Seeder
职责 定义单模型假数据模板 编排整体填充流程
随机数据 内置 Faker,天生支持 本身不管随机,可调用 Factory
关联数据 一行代码带出关联 需借助 Factory 或手写
典型场景 开发环境造量、单元测试 初始化基础数据(角色、字典表)、演示数据
执行方式 被调用,不单独运行 php artisan db:seed 直接运行

一句话:初始化"必须有"的数据用 Seeder 手写,造"看着像真的"的大量数据用 Factory,两者在 DatabaseSeeder 里会师。

常见问题(FAQ)

Q:生产环境能跑 Seeder 吗?
A:可以但要谨慎——幂等初始化字典表可使用受审查 Seeder;创建管理员应走受控身份流程,不使用示例固定密码;测试假数据绝不该进生产。可用 --class 限定范围,检查连接、备份与回退,代码环境限制不能替代数据库权限隔离。

Q:Factory 生成的中文数据怎么弄?
A:在 config/app.php 或 AppServiceProvider 中把 Faker locale 设为 zh_CN,Faker 就会产出中文姓名、地址等本地化假数据。

Q:老项目的 factory(App\User::class, 50) 写法报错?
A:那是 Laravel 7 及之前的全局函数式写法。8+ 改为类式 Factory:模型加 HasFactory trait,用 User::factory()->count(50)->create()。升级时需逐个迁移。

参考资料

本文依据官方资料核对,未进行现场运行测试;代码与配置示例需结合实际版本、权限和环境验证。

延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台