Laravel 7.x自定义数组验证:验证设备归属所选设备厂商
解决Laravel中设备与所属公司的动态验证问题
嘿,我来帮你搞定这个验证问题!你遇到的核心问题是Laravel默认的exists规则没法动态引用请求数组里同层级的其他字段,所以咱们得用自定义逻辑来确保每个device_id确实属于对应的device_company_id,防止恶意篡改。
方法一:使用闭包结合默认exists规则(更简洁)
不需要单独创建规则类,直接在验证规则里用闭包动态添加查询条件:
use Illuminate\Validation\Rule; // 你的原有规则合并逻辑 $rules = array_merge($rules, [ 'devices' => [ 'required', 'array' ], 'devices.*.device_company_id' => [ 'required', 'integer', 'exists:device_companies,id,company_id,' . auth()->user()->id ], 'devices.*.device_id' => [ 'required', 'integer', Rule::exists('devices', 'id')->where(function ($query) use ($attribute) { // 从字段名中提取数组索引,比如从"devices.0.device_id"拿到索引0 $index = explode('.', $attribute)[1]; // 获取当前设备对应的device_company_id $deviceCompanyId = request()->input("devices.{$index}.device_company_id"); // 添加查询条件:设备必须属于指定的device_company_id $query->where('device_company_id', $deviceCompanyId); }) ], ]);
方法二:创建自定义验证规则类(更易复用)
如果这个验证逻辑在多个地方用到,推荐单独创建规则类:
1. 生成规则类
运行Artisan命令:
php artisan make:rule DeviceBelongsToCompany
2. 编写规则逻辑
修改app/Rules/DeviceBelongsToCompany.php:
<?php namespace App\Rules; use Illuminate\Contracts\Validation\Rule; use Illuminate\Support\Facades\DB; class DeviceBelongsToCompany implements Rule { protected $deviceCompanyId; // 构造函数接收对应的device_company_id public function __construct($deviceCompanyId) { $this->deviceCompanyId = $deviceCompanyId; } // 验证逻辑:检查设备是否属于指定公司 public function passes($attribute, $value) { return DB::table('devices') ->where('id', $value) ->where('device_company_id', $this->deviceCompanyId) ->exists(); } // 自定义错误提示信息 public function message() { return '所选设备不属于指定的设备公司,请检查输入。'; } }
3. 在验证规则中使用自定义规则
// 你的原有规则合并逻辑 $rules = array_merge($rules, [ 'devices' => [ 'required', 'array' ], 'devices.*.device_company_id' => [ 'required', 'integer', 'exists:device_companies,id,company_id,' . auth()->user()->id ], 'devices.*.device_id' => [ 'required', 'integer', function ($attribute, $value, $fail) { // 提取数组索引 $index = explode('.', $attribute)[1]; $deviceCompanyId = request()->input("devices.{$index}.device_company_id"); // 实例化自定义规则并验证 $rule = new \App\Rules\DeviceBelongsToCompany($deviceCompanyId); if (!$rule->passes($attribute, $value)) { $fail($rule->message()); } } ], ]);
为什么原有写法不行?
Laravel默认的exists规则参数是静态值,无法动态引用请求中同层级的其他字段(比如devices.*.device_company_id),所以必须通过闭包或自定义规则来实现这种动态关联验证,确保请求数据的合法性。
内容的提问来源于stack exchange,提问作者Mr.Singh
相关产品推荐
相关产品推荐

