Laravel批量对象数组验证报错及数组转对象数组咨询
Laravel多对象数组验证问题解决方法
问题场景
- API接收单个对象的数组时,验证与入库操作均正常,示例请求格式:
[ { "datetime": "2022-07-19 12:04:03", "receiptNumber" : "4010", "isRefund": 0, "amount" : 1025 } ]
- 但传入多个对象的数组时,尝试用
foreach遍历数组元素并调用$this->validate()验证时出现错误,示例请求格式:
[ { "datetime": "2022-07-19 12:04:03", "receiptNumber" : "4010", "isRefund": 0, "amount" : 1025 }, { "datetime": "2022-07-19 12:04:03", "receiptNumber" : "4009", "isRefund": 0, "amount" : 1025 } ]
错误代码
$array = $request->all(); foreach($array as $sdsa){ $this->validate($sdsa, [ 'datetime' => 'required|date_format:Y-m-d H:i:s', 'amount' => 'required|numeric', 'isRefund' => 'required|integer|between:0,1', 'receiptNumber' => 'required|string', ]); }
报错信息
"message": "Argument 1 passed to App\\Http\\Controllers\\Controller::validate() must be an instance of Illuminate\\Http\\Request, array given"
用户核心需求:将单个关联数组(如下)转换为$this->validate()可接收的结构(本质是转为Request实例):
array:4 [ "datetime" => "2022-07-19 12:04:03" "receiptNumber" => "4010" "isRefund" => 0 "amount" => 1025 ]
解决方法
方法一:将数组包装成Request实例
$this->validate()的第一个参数必须是Illuminate\Http\Request对象,因此可以把遍历到的数组直接实例化为Request对象:
use Illuminate\Http\Request; $array = $request->all(); foreach($array as $item){ // 把单个数组转成Request实例 $singleRequest = new Request($item); $this->validate($singleRequest, [ 'datetime' => 'required|date_format:Y-m-d H:i:s', 'amount' => 'required|numeric', 'isRefund' => 'required|integer|between:0,1', 'receiptNumber' => 'required|string', ]); // 验证通过后执行入库逻辑 }
方法二:用Validator门面直接验证数组(更推荐)
不需要转换Request对象,直接使用Validator类验证数组,逻辑更清晰:
use Illuminate\Support\Facades\Validator; $array = $request->all(); foreach($array as $item){ $validator = Validator::make($item, [ 'datetime' => 'required|date_format:Y-m-d H:i:s', 'amount' => 'required|numeric', 'isRefund' => 'required|integer|between:0,1', 'receiptNumber' => 'required|string', ]); if ($validator->fails()) { // 处理验证失败,比如返回错误响应 return response()->json(['errors' => $validator->errors()], 422); } // 验证通过后执行入库逻辑 }
额外优化:批量验证整个数组
如果想一次性验证所有数组元素,可直接使用数组通配符规则,无需循环验证:
$this->validate($request, [ '*.datetime' => 'required|date_format:Y-m-d H:i:s', '*.amount' => 'required|numeric', '*.isRefund' => 'required|integer|between:0,1', '*.receiptNumber' => 'required|string', ]); // 验证通过后遍历入库 $array = $request->all(); foreach($array as $item){ // 执行入库逻辑 }
内容的提问来源于stack exchange,提问作者Mohamed hassan
相关产品推荐
相关产品推荐

