Yii2 2.0.15.1(PHP7.0.27)触发checkAva验证时出现无效JSON数据错误
我之前处理过类似的问题,结合你提供的环境(Yii2 2.0.15.1 + PHP7.0.27)和代码场景,这个「Invalid JSON data」错误大概率和Yii2对多文件上传请求的JSON解析逻辑以及自定义验证的执行时机有关,下面给你梳理具体的原因和解决方案:
问题根源分析
Yii2在处理包含multipart/form-data的请求(比如带文件上传的请求)时,会自动尝试解析请求体中的JSON数据,但2.0.15.x版本在这个逻辑上存在小缺陷。当你的checkAva自定义验证在文件上传解析完成前执行,或者验证函数内部意外操作了请求对象,就会触发JSON解析失败的错误。另外,验证规则的执行顺序也可能影响这个过程——如果自定义验证先于文件验证执行,会干扰请求数据的正常解析。
具体解决方案
1. 检查并修正checkAva函数的内部逻辑
先排查你的checkAva函数,看看是否有直接操作请求对象的代码(比如读取/修改Yii::$app->request的参数)。自定义验证应该只依赖模型已加载的属性,不要直接操作请求对象:
public function checkAva($attribute, $params) { // 错误示例:直接读取请求数据,会干扰解析过程 // $caid = Yii::$app->request->post('caid'); // 正确做法:使用模型自身的属性 $caid = $this->caid; // 替换成你实际需要的模型属性 // 后续的验证逻辑... }
2. 调整验证规则的执行顺序
Yii2的验证规则是按数组顺序执行的,把docs字段的文件上传验证放在checkAva自定义验证之前,确保文件上传的解析先完成,再执行自定义验证:
public function rules() { return [ // 先处理文件上传验证,确保请求数据解析完成 ['docs', 'file', 'maxFiles' => 10, 'skipOnEmpty' => true], // 再执行自定义验证 ['available', 'checkAva', 'skipOnEmpty' => true, 'on' => 'create'], ]; }
3. 升级Yii2版本(推荐)
Yii2 2.0.16及后续版本修复了多个关于multipart/form-data请求解析的bug,如果你的项目允许升级,直接升级到最新的稳定版本(比如2.0.47)可以从根源上解决这个问题,同时还能获得更多安全补丁和功能优化。
4. 手动配置请求解析器(临时 workaround)
如果暂时无法升级版本,可以在控制器或全局配置中手动指定请求解析器,避免自动解析JSON时出错:
控制器中配置
public function behaviors() { $behaviors = parent::behaviors(); // 为multipart请求指定正确的解析器 $behaviors['contentNegotiator']['formats']['multipart/form-data'] = 'application/json'; return $behaviors; }
全局配置(config/web.php)
return [ // ...其他配置 'components' => [ 'request' => [ 'parsers' => [ 'multipart/form-data' => 'yii\web\MultipartFormDataParser', ], ], ], ];
内容的提问来源于stack exchange,提问作者Chonjaroen Chauynoo

