Laravel多图上传:如何在验证错误中显示文件名并优化展示
解决Laravel多图上传验证错误显示问题
一、让验证错误信息包含文件名
默认验证错误会以uploads.0这类索引标识错误文件,我们需要将其替换为对应上传文件的原始名称,步骤如下:
修改控制器验证失败后的错误处理逻辑
在验证失败时,遍历错误信息并替换索引为文件名:if ($validator->fails()) { // 获取所有上传的文件 $uploadedFiles = $request->file('uploads') ?? []; $customErrors = []; foreach ($validator->errors()->getMessages() as $field => $messages) { // 匹配uploads.N格式的字段 if (preg_match('/^uploads\.(\d+)$/', $field, $matches)) { $index = $matches[1]; // 获取对应文件的原始名称,不存在则显示"未知文件" $fileName = isset($uploadedFiles[$index]) ? $uploadedFiles[$index]->getClientOriginalName() : '未知文件'; // 替换错误消息中的索引为文件名 foreach ($messages as $msg) { $customErrors[] = str_replace($field, $fileName, $msg); } } else { // 非上传字段的错误保持原样 $customErrors = array_merge($customErrors, $messages); } } return redirect()->route('shipping.create') ->withErrors(['custom' => $customErrors]) ->withInput(); }(可选)优化错误消息模板
在resources/lang/zh-CN/validation.php中添加更友好的自定义消息:'image' => ':attribute 必须是图片文件。', 'mimes' => ':attribute 必须是以下类型的文件: :values。',替换后错误消息会变成类似
"xxx.pdf 必须是图片文件。"的格式。
二、将错误提示显示在文件输入框下方
移除全局统一的错误警告框,改为在文件输入字段下方展示对应错误:
删除Blade中的全局错误警告框
移除以下代码:@if (count($errors) > 0) <div class="alert alert-danger"> <ul> @foreach ($errors->all() as $error) <li>{{ $error }}</li> @endforeach </ul> </div> @endif在文件输入框下方添加错误展示代码
在多文件输入字段(如<input type="file" name="uploads[]" multiple>)下方插入:<div class="error text-danger fs-6 fw-400"> @if($errors->has('custom')) @foreach($errors->get('custom') as $error) <p>{{ $error }}</p> @endforeach @endif </div>保留其他字段的错误显示逻辑
其他字段(如shipping_code)的错误展示代码保持不变:@if($errors->has('shipping_code')) <div class="error text-danger fs-6 fw-400">{{ $errors->first('shipping_code') }}</div> @endif
完整控制器代码示例
public function store(Request $request) { $validator = Validator::make($request->all(),[ 'shipping_code' => 'required|string', 'customer_name' => 'required|exists:users,id', 'shipper_name' => 'nullable|exists:users,id', 'shipping_details' => 'nullable|string', 'pickup_date' => 'required|date', 'delivery_date' => 'nullable|date', 'driver_name' => 'required|exists:users,id', 'driver_fee' => 'required|regex:/^\d+(\.\d{1,2})?$/', 'transaction_fee' => 'required|regex:/^\d+(\.\d{1,2})?$/', 'remarks' => 'nullable|string', 'status' => 'required|in:0,1,2,3', 'uploads' => 'required', 'uploads.*' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048' ]); if ($validator->fails()) { $uploadedFiles = $request->file('uploads') ?? []; $customErrors = []; foreach ($validator->errors()->getMessages() as $field => $messages) { if (preg_match('/^uploads\.(\d+)$/', $field, $matches)) { $index = $matches[1]; $fileName = isset($uploadedFiles[$index]) ? $uploadedFiles[$index]->getClientOriginalName() : '未知文件'; foreach ($messages as $msg) { $customErrors[] = str_replace($field, $fileName, $msg); } } else { $customErrors = array_merge($customErrors, $messages); } } return redirect()->route('shipping.create') ->withErrors(['custom' => $customErrors]) ->withInput(); } else{ DB::transaction(function () use($request) { $exPd = explode(',',$request->driver_name); $driver_id = $exPd[0]; $shipping = new Shipping(); $shipping->shipping_code = $request->shipping_code; $shipping->customer_id = $request->customer_name; $shipping->shipper_id = $request->shipper_name; $shipping->driver_id = $driver_id; $shipping->shipping_details = $request->shipping_details; $shipping->pickup_date = convertDateToDB($request->pickup_date); $shipping->delivery_date = convertDateToDB($request->delivery_date); $shipping->driver_fee = $request->driver_fee; $shipping->transaction_amount = $request->transaction_fee; $shipping->remarks = $request->remarks; $shipping->status = $request->status; $shipping->created_at = date('Y-m-d H:i:s'); $shipping->created_by = Auth::user()->id; $shipping->save(); if($request->hasfile('uploads')) { foreach($request->file('uploads') as $file) { $input['imagename'] = time().'.'.$file->extension(); $filePath = public_path('/uploads/shipping_transaction_images/'); $img = Image::make($file->path()); $img->resize(110, 110, function ($const) { $const->aspectRatio(); })->save($filePath.$input['imagename']); $imgData[] = $input['imagename']; $fileModal = new ShippingImage(); $fileModal->shipping_id = $shipping->id; $fileModal->image_type = 'pickup'; $fileModal->image_file = $input['imagename']; $fileModal->save(); } } }); return redirect()->route('shippings.index') ->with('success','Shipping Transaction Created Successfully'); } }
内容的提问来源于stack exchange,提问作者Baby Babai
相关产品推荐
相关产品推荐

