Laravel:languages.*.description匹配gb时移除required验证规则
解决方案
方法1:自定义闭包规则(无需提前知晓语言代码)
利用Laravel的闭包验证规则,解析字段名中的语言代码,动态判断是否需要必填校验:
public function rules(): array { return [ 'languages.*.description' => [ 'string', function ($attribute, $value, $fail) { // 从字段名中提取语言代码(比如从languages.gb.description中拿到gb) if (preg_match('/languages\.(\w+)\.description/', $attribute, $matches)) { $langCode = $matches[1]; // 只有当语言代码不是gb且值为空时,抛出验证错误 if ($langCode !== 'gb' && trim($value) === '') { $fail("The $attribute field is required."); } } } ], ]; }
这个方法无需提前知道所有可能的语言代码,通配符规则依然生效,同时针对gb特例跳过必填校验,灵活性拉满。
方法2:动态生成规则数组(明确控制每个字段)
如果能提前获取请求中的语言列表,可以遍历生成对应字段的规则,避免通配符的模糊处理:
public function rules(): array { $rules = []; // 获取请求中的languages数组键名 $languageKeys = array_keys($this->input('languages', [])); foreach ($languageKeys as $code) { $field = "languages.$code.description"; $rules[$field] = ['string']; // 非gb语言才添加required规则 if ($code !== 'gb') { $rules[$field][] = 'required'; } } // 可选:添加兜底规则,处理请求中未提交但可能存在的其他语言字段 $rules['languages.*.description'][] = 'string'; return $rules; }
这种方法规则清晰,每个字段的校验逻辑一目了然,适合需要精准控制的场景。
方法3:扩展自定义验证规则(复用性更高)
如果这个校验逻辑需要在多个地方复用,可以创建自定义验证规则:
- 生成自定义规则类:
php artisan make:rule RequiredUnlessLanguageIsGb
- 实现规则逻辑:
namespace App\Rules; use Illuminate\Contracts\Validation\Rule; class RequiredUnlessLanguageIsGb implements Rule { protected $attribute; public function passes($attribute, $value) { $this->attribute = $attribute; // 提取语言代码并判断 if (preg_match('/languages\.(\w+)\.description/', $attribute, $matches)) { return $matches[1] === 'gb' || !empty(trim($value)); } return true; } public function message() { return "The $this->attribute field is required."; } }
- 在验证规则中使用:
use App\Rules\RequiredUnlessLanguageIsGb; public function rules(): array { return [ 'languages.*.description' => ['string', new RequiredUnlessLanguageIsGb], ]; }
这种方式适合需要在多个表单请求中复用该校验逻辑的场景,代码更易维护。
内容的提问来源于stack exchange,提问作者Cudos
相关产品推荐
相关产品推荐

