在 Laravel 迁移中直接传入 Enum::cases() 会报错,需通过 array_map 提取枚举项的 name 字符串数组,再传给 enum() 方法,才能正确创建数据库 ENUM 字段。
在
laravel
迁移中直接传入 `enum::cases()` 会报错,需通过 `array_map` 提取枚举项的 `name` 字符串数组,再传给 `enum()` 方法,才能正确创建数据库 enum 字段。
PHP 8.1 引入的原生枚举(enum)是类型安全、语义清晰的优秀特性,但在 Laravel 迁移中直接集成需注意底层限制:Laravel 的 Blueprint::enum() 方法仅接受
字符串值数组
(如 ['Monday', 'Tuesday', ...]),而 DayOfWeek::cases() 返回的是 DayOfWeek 枚举实例数组,无法直接用于数据库字段定义。
✅ 正确写法如下(以 school_days 表为例):
对应的枚举类应定义为:
⚠️ 注意事项:
PHP 8.5.5
PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。
下载
立即学习
“
PHP免费学习笔记(深入)
”;
推荐使用 string-backed enum
(即 enum DayOfWeek: string),便于与数据库字符串值对齐,并支持 -youjiankuohao
php
cnvalue 映射(如存 'monday' 而非 'Monday'),更符合 Laravel 惯例和大小写敏感场景;
若使用纯 case 枚举(无 backing type),则必须用 ->name(如 'Monday'),但需确保数据库字段大小写与应用逻辑一致;
MySQL 的 ENUM 类型区分大小写且不支持动态扩展,生产环境建议配合模型访问器(accessor/mutator)或使用 cast 自动转换,例如在模型中添加:
这样,读取时自动转为枚举实例,写入时自动使用 ->value(string-backed)或 ->name,实现类型安全闭环。
总结:Laravel 迁移本身不“理解”PHP 枚举对象,但可通过 Enum::cases() + array_map 轻松桥接;配合模型属性类型转换,即可在全栈层面享受原生枚举带来的可维护性与安全性提升。
// database/migrations/xxxx_xx_xx_create_school_days_table.php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(Blueprint $table)
{
Schema::create('school_days', function (Blueprint $table) {
$table->id();
// ✅ 正确:将枚举 case 转为 name 字符串数组
$table->enum('day_of_week', array_map(
fn(\App\Enums\DayOfWeek $case) => $case->name,
\App\Enums\DayOfWeek::cases()
));
$table->timestamps();
});
}
public function down(Blueprint $table)
{
Schema::dropIfExists('school_days');
}
};// app/Enums/DayOfWeek.php
// app/Models/SchoolDay.php
protected $casts = [
'day_of_week' => \App\Enums\DayOfWeek::class,
];