laravel 8–11中seeder与factory核心逻辑不变,但工厂必须用类式定义并声明$model属性,seeder须置于database/seeders/且命名空间为database\seeders,批量插入推荐user::factory()->count(n)->create(),--force不自动清表。

在 Laravel 8 到 Laravel 11 的演进中,数据库填充(Seeder)与模型工厂(Factory)的核心逻辑未变,但语法、路径、命名空间和默认行为有实质性调整。关键不是“能不能用”,而是“怎么写才不报错、不静默失败”。下面直说变化点和实操要点。
工厂类定义方式:从闭包式到类式,且必须声明$model属性
Laravel 7 及以前支持闭包式工厂($factory->define(...)),Laravel 8+ 全面弃用,强制使用面向类的工厂,并要求显式指定 protected $model。
- Laravel 8–11 工厂必须继承
Illuminate\Database\Eloquent\Factories\Factory -
definition()方法必须返回数组,不能返回模型实例 - 不再自动识别模型命名空间,
--model=User生成时若模型在App\Models\User,需确保该路径正确;Laravel 9+ 默认模型路径为App\Models,但工厂内仍要写全:protected $model = \App\Models\User::class; - Faker 实例统一通过
$this->faker访问,无需手动注入参数
Seeder 文件位置与命名空间:database/seeders/ + Database\Seeders
Laravel 8 起彻底废弃 database/seeds/ 路径,所有 Seeder 必须放在 database/seeders/ 下,且类声明命名空间必须是 namespace Database\Seeders;。
- 旧写法
namespace App\Database\Seeders;或无命名空间 → 运行时报Class not found - 文件名与类名严格一致(大小写敏感),例如
UserSeeder.php对应class UserSeeder - Laravel 9+ 的
DatabaseSeeder.php默认为空,不会自动包含新创建的 Seeder,必须手动在run()中调用$this->call(UserSeeder::class) - 忘记注册或拼错类名,
php artisan db:seed不报错也不插入数据——这是最常见静默失败原因
批量插入语法:Factory→create() 成为主流,DB::insert() 仍可用但需注意字段对齐
语法层面变化不大,但约束更严:
-
User::factory()->count(100)->create()是推荐写法,支持关联嵌套(如has(Profile::factory()))、状态覆盖(state([...])) - 使用
DB::table('users')->insert($data)时,$data必须是二维关联数组,键名与数据库字段名完全一致(如email_verified_at不能写成emailVerifiedAt) - 时间字段必须传
now()、Carbon::now()等 DateTime 实例,传字符串(如'2026-06-03')会导致插入0000-00-00 00:00:00 - 禁止在循环中调用
save()或create()—— 单条查询 + Eloquent 开销在 Laravel 11 下更容易触发内存限制
运行命令与环境控制:--force 不清表,--class 指定类更常用
命令行为基本一致,但语义更明确:
-
php artisan db:seed:只执行DatabaseSeeder中注册的 Seeder -
php artisan db:seed --class=UserSeeder:跳过入口,直接运行指定类(适合调试单个填充器) -
--force仅绕过“非开发环境禁止填充”的检查,不会自动清空表;如需重置,需在 Seeder 中手动DB::table('users')->truncate();或结合迁移回滚 - Laravel 11 默认启用
APP_ENV=local才允许db:seed,生产环境必须加--force,否则直接拒绝执行











