应直接在 run() 方法参数声明 Faker $faker,由 Laravel 自动注入配置好 locale 和 provider 的实例;手动 new 会导致中文失效、unique() 失效及 provider 未加载等问题。

直接在 run() 方法参数里声明 Faker $faker,别 new \Faker\Generator(),否则中文、unique()、扩展方法全失效。
Seeder 里怎么正确拿到 Faker 实例
Laravel 会自动把配置好 locale 和 provider 的 Faker 实例注入到 run() 方法参数中。手动 new 会导致:
-
$faker->name()返回空或报错(provider 没加载) -
zh_CNlocale 生效不了,始终是英文数据 -
unique()内部计数器不工作,邮箱/用户名重复触发唯一约束
正确写法:
public function run(Faker $faker)
{
$faker->seed(123); // 可选:固定随机种子
DB::table('users')->insert([
'name' => $faker->name,
'email' => $faker->unique()->safeEmail,
]);
}
Faker 字段类型和数据库字段必须对得上
填错类型是 SQL 报错最常见原因,尤其是整型、JSON、时间字段:
- TINYINT / BOOLEAN 列 → 用
$faker->boolean(),别用$faker->word() -
created_at/updated_at→ 用$faker->dateTimeBetween('-1 year', 'now'),别拼字符串'2024-01-01' - JSON 列(如
meta)→ 必须json_encode($faker->randomElements(['a','b'], 2)),确保是合法 JSON 字符串 - ID 主键 → 让数据库自增,Seeder 里别塞
$faker->numberBetween();仅关联测试需指定 ID 时才手动设
批量插入几千条?绕过 Eloquent 直接 DB::table()->insert()
User::factory()->count(1000)->create() 是逐条 INSERT + 触发模型事件,慢且易超时。真要插大量测试数据,优先走原生批量:
- 速度提升 5–10 倍,1000 条通常压进 200ms 内
- 字段名必须和数据库列名完全一致(
created_at≠createdAt) - 时间字段得自己转成
Y-m-d H:i:s格式,now()或$faker->dateTime...返回对象,不能直接塞 - 记得提前
$faker->seed(1),否则unique()在大数组里可能撞车 - 如果非要用模型(比如要跑
creating事件),至少加DB::statement('SET FOREIGN_KEY_CHECKS=0')关外键检查
中文、手机号、身份证号总校验失败?不是 Faker 问题,是规则太严
Faker zh_CN 提供的手机号格式是 13812345678,但很多验证正则写成 /^1[3-9]\d{9}$/——它只认 11 位,而 Faker 生成的是 11 位,没问题;真正卡住的是第三方身份证校验库,它们要求算法校验最后一位,而 Faker 生成的是「形似」但不满足 Luhn 算法的号码。
解决办法:
- 手机号:坚持用
$faker->phoneNumber(),它在zh_CN下输出就是合规 11 位 - 身份证号:改用
fake()->idCardNumber()(需确认 Faker 版本 ≥ 1.21.0,且已加载zh_CNprovider) - 若仍失败,说明你用的校验逻辑依赖真实算法——那就别用 Faker 生成,改用固定测试值或专用库如
overtrue/laravel-china-identity-card
最容易被忽略的一点:Faker 的 unique() 是内存级去重,不跨 Seeder、不跨进程;批量生成前不 seed(),同一运行中多次调用 unique()->email 仍可能重复。


















