
laravel 8 引入了全新的模型工厂(model factory)机制,旨在提供更结构化、更易于维护的测试数据生成方式。与 laravel 7 及早期版本中依赖全局 $factory 实例和闭包定义工厂的方式不同,laravel 8 将每个模型的工厂定义封装为独立的 php 类。这一变化要求开发者在升级项目时对现有工厂进行重构。
对于时间有限或不希望立即进行大规模重构的项目,Laravel 提供了一个兼容包 laravel/legacy-factories。安装此包后,您可以在 Laravel 8 项目中继续使用 Laravel 7 风格的工厂定义。
composer require laravel/legacy-factories
注意事项:
全面重构是拥抱 Laravel 8 新工厂机制的最佳实践。这种方式将工厂定义从全局闭包转变为独立的类,提高了代码的可读性和可维护性。
在 Laravel 7 中,工厂通常定义在一个全局的 database/factories/Factory.php 文件中,或分散在多个工厂文件中,通过 $factory->define() 方法将模型与数据生成逻辑关联起来:
Laravel 7 工厂示例
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use App\Login;
use Faker\Generator as Faker;
$factory->define(Login::class, function (Faker $faker) {
$randomDateTime = $faker->dateTimeBetween('-6 hours', 'now');
return [
'user_id' => factory(App\User::class),
'tenant_id' => factory(App\Tenant::class),
'created_at' => $randomDateTime,
'updated_at' => $randomDateTime,
];
});而在 Laravel 8 中,每个模型都应拥有一个对应的工厂类。这些工厂类通常位于 database/factories 目录下,并遵循 ModelNameFactory.php 的命名约定。它们继承自 Illuminate\Database\Eloquent\Factories\Factory 类,并将数据生成逻辑封装在 definition() 方法中。
Laravel 8 类式工厂示例
<?php
namespace Database\Factories;
use App\Models\Login; // 确保使用正确的模型命名空间
use App\Models\User;
use App\Models\Tenant;
use Illuminate\Database\Eloquent\Factories\Factory;
class LoginFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = Login::class; // 明确指定关联的模型
/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
// 注意这里 $this->faker 的使用方式,而不是闭包参数 $faker
$randomDateTime = $this->faker->dateTimeBetween('-6 hours', 'now');
return [
'user_id' => User::factory(), // 调用关联模型的工厂
'tenant_id' => Tenant::factory(), // 调用关联模型的工厂
'created_at' => $randomDateTime,
'updated_at' => $randomDateTime,
];
}
}核心差异总结:
为了让 Laravel 能够自动发现并使用模型的工厂,您需要在对应的 Eloquent 模型中引入 Illuminate\Database\Eloquent\Factories\HasFactory Trait。
app/Models/Login.php 模型示例
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Login extends Model
{
use HasFactory; // 引入 HasFactory Trait
// ... 其他模型定义
}当模型使用了 HasFactory Trait 后,您就可以直接通过 Login::factory() 语法来创建模型实例,而 Laravel 会自动查找 database/factories/LoginFactory.php 文件。
在 Laravel 7 中,您可能使用 factory(App\User::class) 来创建关联模型实例。在 Laravel 8 中,当关联模型也使用了 HasFactory Trait 并有对应的工厂类时,您可以通过 Model::factory() 语法来创建关联实例。
例如,在 LoginFactory 中创建 User 和 Tenant 实例:
// ... 在 LoginFactory 的 definition() 方法中
return [
'user_id' => User::factory(), // 创建一个 User 实例并获取其 ID
'tenant_id' => Tenant::factory(), // 创建一个 Tenant 实例并获取其 ID
// ...
];重要提示:
我们将原始的 Laravel 7 Login 模型工厂重构到 Laravel 8。
原始 Laravel 7 工厂 (database/factories/Factory.php 或类似文件)
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use App\Login;
use Faker\Generator as Faker;
$factory->define(Login::class, function (Faker $faker) {
$randomDateTime = $faker->dateTimeBetween('-6 hours', 'now');
return [
'user_id' => factory(App\User::class),
'tenant_id' => factory(App\Tenant::class),
'created_at' => $randomDateTime,
'updated_at' => $randomDateTime,
];
});重构后的 Laravel 8 工厂 (database/factories/LoginFactory.php)
<?php
namespace Database\Factories;
use App\Models\Login; // 确保模型命名空间正确
use App\Models\Tenant;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class LoginFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = Login::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
$randomDateTime = $this->faker->dateTimeBetween('-6 hours', 'now');
return [
'user_id' => User::factory(),
'tenant_id' => Tenant::factory(),
'created_at' => $randomDateTime,
'updated_at' => $randomDateTime,
];
}
}对应的 Login 模型 (app/Models/Login.php)
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Login extends Model
{
use HasFactory;
// ... 其他模型定义
}此外,您还需要确保:
以上就是Laravel 7 工厂重构至 Laravel 8:新范式与实践指南的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号