Laravel多字段上传报错:Attempt to read property 'drugid' on string
问题排查:Attempt to read property 'drugid' on string
问题场景
在Laravel项目中,尝试通过Blade视图遍历多组输入字段,使用查询构建器批量插入数据到数据库时,出现报错:Attempt to read property 'drugid' on string。
前端HTML示例
<input type="text" name="drugname[]"> <input type="text" name="drugname[]"> <input type="text" name="drugname[]">
控制器处理代码
public function prescribedrugs(Request $presdrug){ $validator = Validator::make($presdrug->all(), [ 'consultclinic' => 'required|string', 'drugdiagnosis' => 'required|string', 'drugpassword' => 'required|string', ]); $getuser = new Getloggedinuserservice(); $getloggedinuser = $getuser->getuser(); if ($validator->fails()) { return response()->json([ 'error' => $validator->errors()->all() ]); }else{ $lastapptid = DB::table('AllDrugPresc')->max('Presc_Num'); $newid = $lastapptid + 1; foreach($presdrug->drugname as $key => $d){ return DB::table('AllDrugPresc') ->insert([ 'Presc_Num'=>$newid, 'Date'=>Carbon::now(), 'Time'=>date('H:i:s'), 'Drug_Id'=>$presdrug->drugid[$key], 'Drug_Name'=>$d, 'Prescription'=>$presdrug->drugprescription[$key], 'Hospital_No'=>'44455eee', 'Surname'=>'rrr', 'Other_Name'=>'rrr', 'Age'=>44, 'Sex'=>'ee', 'Account'=>'ee', 'Account_Category'=>'ddd', 'Clinic'=>$presdrug->consultclinic, 'Diagnosis'=>$presdrug->drugdiagnosis, 'Prescribed_By'=>'wwwe', 'Qty_given'=>2, 'Total_Cost'=>33 ]); } } }
错误原因分析
前端缺少对应数组字段:控制器代码中使用了
$presdrug->drugid[$key]和$presdrug->drugprescription[$key],但前端仅提供了drugname[]输入,未提交drugid[]和drugprescription[]数组。当Laravel接收不到对应数组时,$presdrug->drugid可能被解析为字符串(或不存在),尝试通过[$key]访问时触发该错误。验证规则未覆盖数组字段:验证器仅校验了
consultclinic等单个字段,未对drugid[]、drugprescription[]这些数组字段做必填校验,导致缺失字段时无法提前拦截错误。循环内提前return:
foreach循环中第一次执行就调用return,会直接终止方法,仅插入第一条数据,后续循环无法执行(虽不是当前报错原因,但属于逻辑缺陷)。
解决方案
1. 补全前端输入字段
确保每组药品对应的drugid、drugname、drugprescription都以数组形式提交,示例:
<!-- 第一组药品 --> <input type="text" name="drugid[]" placeholder="药品ID"> <input type="text" name="drugname[]" placeholder="药品名称"> <input type="text" name="drugprescription[]" placeholder="处方说明"> <!-- 第二组药品 --> <input type="text" name="drugid[]" placeholder="药品ID"> <input type="text" name="drugname[]" placeholder="药品名称"> <input type="text" name="drugprescription[]" placeholder="处方说明">
2. 更新验证规则
添加数组字段的校验,确保每个子字段都符合要求:
$validator = Validator::make($presdrug->all(), [ 'consultclinic' => 'required|string', 'drugdiagnosis' => 'required|string', 'drugpassword' => 'required|string', 'drugid.*' => 'required|string', // 校验每个drugid必填且为字符串 'drugname.*' => 'required|string', 'drugprescription.*' => 'required|string', ]);
3. 修复循环逻辑
移除循环内的return,确保所有数据都能插入,循环结束后统一返回响应:
foreach($presdrug->drugname as $key => $d){ DB::table('AllDrugPresc') ->insert([ 'Presc_Num'=>$newid, 'Date'=>Carbon::now(), 'Time'=>date('H:i:s'), 'Drug_Id'=>$presdrug->drugid[$key], 'Drug_Name'=>$d, 'Prescription'=>$presdrug->drugprescription[$key], 'Hospital_No'=>'44455eee', 'Surname'=>'rrr', 'Other_Name'=>'rrr', 'Age'=>44, 'Sex'=>'ee', 'Account'=>'ee', 'Account_Category'=>'ddd', 'Clinic'=>$presdrug->consultclinic, 'Diagnosis'=>$presdrug->drugdiagnosis, 'Prescribed_By'=>'wwwe', 'Qty_given'=>2, 'Total_Cost'=>33 ]); } // 循环完成后返回成功响应 return response()->json(['success' => '药品处方已批量保存']);
4. 优化Presc_Num生成逻辑(可选)
直接使用max('Presc_Num')+1存在并发风险(多个请求同时操作时可能生成重复ID),建议:
- 将
Presc_Num设为数据库自增字段,插入时无需手动生成; - 或使用数据库事务包裹ID生成与插入操作,确保唯一性。
内容的提问来源于stack exchange,提问作者elo
相关产品推荐
相关产品推荐

