yii2 restful api 验证需超越模型静态规则,应结合动态模型、运行时规则、自定义验证器及控制器统一拦截,在入口处明确约束参数结构与业务逻辑。

在 Yii2 构建 RESTful API 时,框架默认通过 rules() 对请求体(如 JSON POST)或查询参数进行验证,但实际开发中常需更灵活的验证逻辑——比如动态字段校验、跨字段约束、或对未定义在模型属性中的参数做校验。这时不能只依赖模型层的静态规则,而需结合行为(Behavior)、自定义验证器、或在控制器中手动触发验证。
在控制器中手动验证非模型字段
当请求参数不绑定到 ActiveRecord 或 FormModel(如过滤条件、分页参数、嵌套 JSON 结构),可构造临时数组并使用 Validator 或 ValidationRule 验证:
- 用
yiialidatorsValidator::validateValue()快速校验单个值(如手机号格式) - 创建轻量级
DynamicForm继承yiiaseModel,动态添加属性和规则 - 在
actionIndex()中提取Yii::$app->request->get()或bodyParams,传入验证
为模型添加运行时规则(Runtime Rules)
若仍使用 Model(如 UserSearch),可在 init() 或 load() 后根据场景动态追加规则:
- 覆盖
rules()方法,内部判断Yii::$app->requestedRoute或请求 method 决定启用哪些规则 - 调用
$this->addRule('field', 'required', ['on' => 'api-create'])添加条件规则 - 对 JSON 请求体中的嵌套字段(如
profile[city]),确保formName()返回空字符串,并用load($data, '')
编写自定义验证器处理复杂逻辑
对于业务强相关的校验(如“密码与确认密码一致”、“结束时间不得早于开始时间”、“用户邮箱必须属于指定域名”),应实现独立验证器:
- 继承
yiialidatorsValidator,重写validateAttribute()或validateValue() - 在模型
rules()中注册:['start_time,end_time', 'app\validators\DateTimeRangeValidator'] - 支持客户端验证:实现
clientValidateAttribute()返回 JS 片段(可选)
统一拦截并增强请求参数验证流程
为避免每个 action 重复写验证逻辑,推荐在控制器基类或行为中集中处理:
- 在
beforeAction()中解析请求参数,调用统一验证服务(如RequestValidator::validate($route, $params)) - 使用
yiiiltersContentNegotiator确保接收 JSON 并自动解析bodyParams - 配合
yiiiltersVerbFilter和自定义异常处理器,将验证失败转为标准 REST 错误响应(422 + 字段错误详情)











