Laravel自定义验证规则如何获取其他字段值参与校验逻辑
自定义金额验证规则获取同表单currency字段值的实现方案
以下是两种常用场景的实现方式,均基于Laravel框架的表单验证逻辑:
方案1:使用闭包验证规则(无需额外创建Rule类,适合简单校验场景)
如果校验逻辑不需要复用,可以直接在表单请求类的rules()方法中通过闭包实现,直接访问当前请求的输入参数即可:
public function rules() { return [ 'currency' => 'required|string', 'amount' => [ 'required', 'numeric', function ($attribute, $value, $fail) { // 两种方式都可以拿到同表单的currency值: // 方式1:通过request()全局辅助函数获取 $currency = request()->input('currency'); // 方式2:表单请求类中直接通过$this获取输入 // $currency = $this->input('currency'); // 按货币类型定义金额上下限示例 $limitConfig = [ 'CNY' => ['min' => 0.01, 'max' => 100000], 'USD' => ['min' => 0.01, 'max' => 20000], 'EUR' => ['min' => 0.01, 'max' => 18000], ]; if (!isset($limitConfig[$currency])) { $fail('不支持的货币类型'); return; } if ($value < $limitConfig[$currency]['min'] || $value > $limitConfig[$currency]['max']) { $fail($attribute . ' 金额必须在' . $limitConfig[$currency]['min'] . '~' . $limitConfig[$currency]['max'] . $currency . '之间'); } } ] ]; }
方案2:自定义独立Rule类(适合逻辑复杂、需要多场景复用的情况)
如果已经单独封装了ValidAmountRule规则类,可以通过构造函数传参的方式把currency值传入规则类:
第一步:编写自定义Rule类
namespace App\Rules; use Illuminate\Contracts\Validation\Rule; class ValidAmountRule implements Rule { // 存储传入的货币类型 protected $currency; // 构造方法接收currency参数 public function __construct($currency) { $this->currency = $currency; } // 校验逻辑 public function passes($attribute, $value) { $limitConfig = [ 'CNY' => ['min' => 0.01, 'max' => 100000], 'USD' => ['min' => 0.01, 'max' => 20000], 'EUR' => ['min' => 0.01, 'max' => 18000], ]; if (!isset($limitConfig[$this->currency])) { return false; } return $value >= $limitConfig[$this->currency]['min'] && $value <= $limitConfig[$this->currency]['max']; } // 错误提示 public function message() { return ':attribute 金额不符合对应货币的有效范围'; } }
第二步:在表单验证规则中调用
public function rules() { return [ 'currency' => 'required|string', // 实例化规则类时直接传入当前请求的currency值 'amount' => ['required', 'numeric', new \App\Rules\ValidAmountRule($this->input('currency'))], ]; }
注意事项
currency字段的校验规则要放在amount之前,确保拿到的currency值已经过必填、格式校验,避免无效值- 如果不需要传参,也可以直接在Rule类的
passes方法中通过request()->input('currency')直接获取值,不过构造函数传参的方式耦合度更低、逻辑更清晰
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

