Laravel Validation:上传有效图片时取消story字段最小字符校验问题
问题原因
你的代码不生效有两个核心问题:
- 修改story校验规则的代码写在
Validator校验执行完成之后,规则已经跑完才修改,完全不会生效 $request->hasFile('photo')只能判断请求里有没有带文件,没法判断文件是否符合格式、大小、上传合法性要求,就算传了违规文件也会命中判断,不符合你要的「仅合法上传图片才取消校验」的要求
实现方案
需要在定义校验规则之前就动态组装story的校验逻辑,结合Laravel自带的条件校验规则实现,修改后的完整store方法代码如下:
public function store(Request $request) { if(Settings::find('active_upload')->value == 0){ toastr()->warning(__('main.new_entries_paused')); return redirect('/'); } // 预定义固定校验规则 $rules = [ 'title' => 'required|string|max:255', 'tags' => 'nullable', 'category_id' => 'required', 'genders_id' => 'required', 'age' => 'required', 'photo' => 'nullable|image|mimes:jpeg,png,jpg|max:2048' ]; $minChar = Settings::find('minimum_characters')->value; $maxChar = Settings::find('maximum_characters')->value; // 动态组装story字段校验规则 $rules['story'] = [ 'required_without:photo', 'string', 'max:'.$maxChar, // 仅当图片未合法上传时,校验最小字符长度 function ($attribute, $value, $fail) use ($minChar, $request) { if (!$request->hasFile('photo') || !$request->file('photo')->isValid()) { if (mb_strlen($value) < $minChar) { $fail('Girilen Metin '.$minChar.' Karakterden Fazla Olmalıdır.'); } } } ]; $messages = [ 'title.required' => 'Bir Başlık Giriniz.', 'title.max' => 'Başlık 255 Karakterden Uzun Olamaz.', 'story.required_without' => 'Boş bırakılmamalıdır.', 'story.max' => 'Girilen Metin ' .$maxChar.' Karakterden Az Olmalıdır.', 'category_id.required' => 'Kategori Seçmeniz Gerekiyor.', 'photo.image' => 'Lütfen Resim Dosyası Yükleyiniz.', 'photo.mimes' => 'Dosya Biçimi jpg,png veya jpeg olmalıdır.', ]; Validator::make($request->all(), $rules, $messages)->validateWithBag('write'); // 后续业务逻辑保持原有逻辑即可 }
逻辑说明
- 所有规则组装都在Validator实例化前完成,从根源避免规则修改滞后不生效的问题
- 用
required_without:photo替代固定的required规则,未上传图片时story才为必填项 - 闭包校验规则会先判断图片合法性:未上传、上传文件格式错误、大小超限、上传失败的场景下,才会校验story的最小字符长度
- 图片合法上传时,自动跳过story的必填和最小长度校验,仅保留最大长度限制,完全匹配需求
内容的提问来源于stack exchange,提问作者takix
相关产品推荐
相关产品推荐

