ThinkPHP 8中应使用带值枚举(Backed Enum)配合内置enum规则校验固定选项字段,如status必须为appenumsStatus中的合法字符串值,支持数组通配符验证及多种运行时校验方式。

在ThinkPHP 8中校验用户提交的「订单状态」「角色类型」「支付方式」等固定选项字段时,必须确保值严格落在预设范围内——用字符串硬编码比对易漏写、难维护,用数据库查询校验又拖慢接口,而原生PHP枚举配合TP8新增的枚举值校验功能,能直接在验证器层拦截非法值,且支持自动反查与IDE智能提示。
定义带值枚举类
在app/enums目录下新建Status.php文件(若目录不存在请手动创建),文件首行必须为<?php ,且【不能有任何空白行或BOM头】:
enum Status: string { case Pending = 'pending'; case Paid = 'paid'; case Shipped = 'shipped'; case Completed = 'completed'; }
这一步必须用Backed Enum(即带string/int值的枚举),纯枚举无法被TP8验证器识别为可校验值域。
立即学习“PHP免费学习笔记(深入)”;
在验证器中启用枚举校验
打开已存在的UserValidate.php(或执行php think make:validate OrderValidate新建),在$rule数组中添加字段规则:
'status' => 'enum:app\enums\Status',
注意命名空间必须用双反斜杠转义,单斜杠会导致类加载失败;枚举类名必须与文件名完全一致(Status.php → Status)。
若传入status=‘delivered’,验证器会直接返回错误:“status必须是枚举app\enums\Status中的有效值”。
高级数组验证:嵌套结构+枚举联动
当接收类似以下JSON数据时:
{"items": [{"product_id": 101, "status": "paid"}, {"product_id": 102, "status": "invalid"}]}
需对items数组内每个元素的status字段单独校验。在验证器中这样写:
修复 Core bailout 状态损坏安全问题,以及 BZ2、DOM、PDO、Opcache/JIT 内存与执行错误,改进 Unicode 字素处理、URL 解析、TLS 流状态、信号分发及会话错误处理。
'items.*.status' => 'enum:app\enums\Status',
这行规则会自动遍历items数组所有子项,对每个status执行枚举值校验。不需要额外循环或自定义方法。
如果还要求product_id为正整数,可合并规则:
'items.*.product_id' => 'require|integer|gt:0',
TP8的高级数组验证支持点号路径语法,*通配符匹配任意索引,无需写成items.0.status、items.1.status。
运行时动态校验枚举值
方法一:使用Validate::make()构造临时验证器
$rules = ['role' => 'enum:app\enums\Role']; $validate = Validate::make($rules); $result = $validate->check(['role' => 'admin']);
方法二:控制器内调用$this->validate()并传入枚举类完整路径
$this->validate($data, ['role' => 'enum:app\enums\Role']);
方法三:在模型save前拦截(适用于业务逻辑强耦合场景)
if (!in_array($data['role'], Role::cases(), true)) { throw new ValidateException('角色值非法'); }
这一步不依赖验证器,但失去错误提示统一管理能力;仅当需要在模型层做原子性判断时选用。


















