迁移中 enum() 字段必须传字符串数组,不能直接调用 cases();需用 array_map 提取 name 或 value;验证用 laravel-validation-rules 的 enum 规则;flaggedenum 不适用 mysql enum,须用整数列配合 casts。

迁移中 enum() 字段必须传字符串数组,不能直接调用 cases()
Blueprint::enum() 方法底层生成的是 MySQL ENUM 类型,它只认字符串字面量列表,不接受 PHP 枚举对象或 cases() 返回的枚举实例数组。直接写 DayOfWeek::cases() 会报错:TypeError: array_map(): Argument #2 ($array) must be of type array, object given 或更隐蔽的“字段定义为空”问题。
- 正确做法是用
array_map(fn ($case) => $case->name, DayOfWeek::cases())提取所有name - 若用
BackedEnum(如enum Status: string),则提取$case->value,而非name - 别在迁移里硬编码字符串(如
['monday', 'tuesday']),否则枚举类改名后迁移就脱节
Laravel 模型访问器要匹配枚举底层类型(string/int)
数据库存的是字符串还是整数,决定了访问器里该用 from() 还是 tryFrom()。存字符串(推荐)时,get* 访问器应返回枚举实例;存整数时,需确保数据库值与枚举的 int 背书值严格一致。
- 字符串背书枚举:用
Status::from($value)(失败抛ValueError)或Status::tryFrom($value)(失败返回null) - 整数背书枚举:同理,但注意 MySQL TINYINT 默认有符号,负值可能触发
tryFrom()返回null - 避免在访问器里做字符串拼接或条件判断替代枚举,那等于放弃类型安全
验证规则要用 laravel-validation-rules 的 Enum 类,别手写 in_array
手写 'status' => 'in:' . implode(',', Status::cases()) 看似简单,但漏掉三件事:不校验类型、不处理空值、不兼容 BackedEnum 的 value 与 name 差异。
- 装包:
composer require laravel-validation-rules/laravel-validation-rules - 规则写法:
'status' => new \LaravelValidationRules\Rules\Enum(Status::class) - 它自动识别
BackedEnum并比对value,纯枚举则比对name,且支持null和空字符串的显式控制
位标志枚举(FlaggedEnum)不能用于 MySQL ENUM 列
BenSampo\Enum\FlaggedEnum 本质是整数位运算,单个字段存多个权限状态。MySQL ENUM 不支持“多选”,强行塞进去只会存第一个值或报错。
- 位标志场景必须用整数列(如
tinyint unsigned),配合模型里的casts使用FlaggedEnum类 - 别在迁移里对位标志枚举调用
getValues()填enum(),那会把所有位组合当成独立选项,逻辑全崩 - 检查权限用
$user->permissions->hasFlag(UserPermissions::EditContent),不是in_array或字符串匹配
name 切换到 value,或者加了新 case 却没跑迁移。这会导致数据库字段允许值与代码可取值不一致,线上出现静默数据截断或验证绕过。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











