laravel 8+ 废弃全局 factory() 函数,必须改用模型静态工厂方法 user::factory()->create(),并确保 database/factories/userfactory.php 存在且正确配置 model 属性、继承 factory 类、定义 definition() 方法。

直接改:把所有 factory(User::class)->create() 这类写法,全部换成 User::factory()->create()。Laravel 7 用的是旧式闭包工厂,8+ 彻底废弃,不改就报 Call to undefined function factory()。
为什么 factory() 函数突然失效
Laravel 8 开始移除全局 factory() 辅助函数,模型工厂改为类驱动——每个模型必须对应一个独立的工厂类,放在 database/factories/ 下,且类名要匹配(如 UserFactory 对应 User 模型)。Laravel 7 的写法在 8+ 环境下根本找不到入口点。
- 旧写法:
factory(App\Models\User::class, 10)->create()或factory('App\Models\User')->make() - 新写法:
App\Models\User::factory()->count(10)->create()或App\Models\User::factory()->make() - 如果你刚升级到 Laravel 8+ 但没生成工厂类,
User::factory()会抛出Unable to locate factory for [App\Models\User]
怎么补上缺失的工厂类
运行命令生成标准工厂类:php artisan make:factory UserFactory --model=User。生成的文件在 database/factories/UserFactory.php,它必须满足三个硬性条件:
-
protected $model = \App\Models\User::class;—— 不能省,不能靠文件名推断 - 继承
\Illuminate\Database\Eloquent\Factories\Factory - 定义
definition()方法,里面用$this->faker->name,不是fake()->name()(后者是辅助函数,仅限 Seeder 或 Blade)
注意命名空间:Laravel 10 推荐显式声明 use Database\Factories\UserFactory;,别依赖自动发现;如果工厂类放在子目录(比如 database/factories/User/UserFactory.php),Laravel 就找不到它。
create() 和 make() 行为差异必须清楚
这不是语法替换问题,而是语义变更点:
-
User::factory()->create():写入数据库,触发creating/created事件,返回已持久化的模型实例($user->exists === true) -
User::factory()->make():只构造内存对象,不入库,不触发事件,$user->exists === false,适合单元测试中绕过 DB - 批量时别混用:
User::factory()->count(10)->make()返回的是集合(Illuminate\Support\Collection),不是数组;而create()才真正插入 10 条记录
如果测试里原来用 factory()->create() 造数据后没清理,升级后依然会残留——工厂本身不负责清库,得靠 RefreshDatabase trait 或手动 truncate。
最常被忽略的是 unique() 的作用域:它只在单次 create() 调用内有效。循环里反复调用 User::factory()->create(),每次都是新工厂实例,$this->faker->unique()->email 不会跨次去重。真要保证唯一,得用 User::factory()->count(100)->create() 一次性批量生成,或者自己加重试逻辑。











