Laravel 9中Foreach循环异常:批量上传后仅一条数据库记录插入
问题分析与解决
问题描述
上传多个文件时,文件能成功保存到指定路径,但数据库表中仅插入一条记录。
问题原因
你在循环外已经实例化了$ac_bg模型对象,每次循环只是修改这个对象的属性后调用save()。第一次调用save()时会插入新记录,之后的save()因为对象已经有了主键ID,会变成更新这条已存在的记录,所以最终数据库里只有一条数据。
修复方案
把模型实例化的代码放到循环内部,每次循环都创建新的模型对象:
// Upload bg_certificateArr photo if ($request->hasFile('bg_certificate')) { foreach ($request->file('bg_certificate') as $key => $file) { // 实例化新的模型对象,替换成你的实际模型类名 $ac_bg = new \App\Models\BankGuarantee(); // 这里改成你的模型类 // 获取图片扩展名 $extention = $file->getClientOriginalExtension(); // 生成新的图片名称 $bgCertImgName = 'ac-bg-cert-' . date('Y-m-d-H-i-s') . '.' . $extention; $bgCertImgPath = 'accountant/images/bank_guarantee/' . $bgCertImgName; // 上传图片 Image::make($file)->save($bgCertImgPath); // 准备关联数据 $bg_amountArr = $data['bg_amount']; $bg_numberArr = $data['bg_number']; $bank_idArr = $data['bank_id']; $bg_from_dateArr = $data['bg_from_date']; $bg_to_dateArr = $data['bg_to_date']; $ac_bg->school_id = $schoolID; $ac_bg->ledgers_id = $acLedger->id; $ac_bg->bg_amount = $bg_amountArr[$key]; $ac_bg->bg_number = $bg_numberArr[$key]; $ac_bg->bank_id = $bank_idArr[$key]; $ac_bg->bg_from_date = $bg_from_dateArr[$key]; $ac_bg->bg_to_date = $bg_to_dateArr[$key]; $ac_bg->bg_certificate = $bgCertImgName; $ac_bg->save(); } }
或者用更简洁的create()方法(需确保模型设置了$fillable属性):
// Upload bg_certificateArr photo if ($request->hasFile('bg_certificate')) { foreach ($request->file('bg_certificate') as $key => $file) { // 获取图片扩展名 $extention = $file->getClientOriginalExtension(); // 生成新的图片名称 $bgCertImgName = 'ac-bg-cert-' . date('Y-m-d-H-i-s') . '.' . $extention; $bgCertImgPath = 'accountant/images/bank_guarantee/' . $bgCertImgName; // 上传图片 Image::make($file)->save($bgCertImgPath); // 使用create方法直接创建新记录 \App\Models\BankGuarantee::create([ 'school_id' => $schoolID, 'ledgers_id' => $acLedger->id, 'bg_amount' => $data['bg_amount'][$key], 'bg_number' => $data['bg_number'][$key], 'bank_id' => $data['bank_id'][$key], 'bg_from_date' => $data['bg_from_date'][$key], 'bg_to_date' => $data['bg_to_date'][$key], 'bg_certificate' => $bgCertImgName ]); } }
注意:使用create()时,必须在模型类中设置$fillable属性,指定允许批量赋值的字段,否则会触发MassAssignmentException异常。
额外优化建议
- 文件名生成可以加入随机字符串,避免同一秒上传多个文件时文件名重复覆盖:
$bgCertImgName = 'ac-bg-cert-' . date('Y-m-d-H-i-s') . '-' . \Illuminate\Support\Str::random(6) . '.' . $extention;
内容的提问来源于stack exchange,提问作者Sudhir Raj
相关产品推荐
相关产品推荐

