Laravel 验证数组 - 如果数组中存在另一个字段,有时会忽略字段

Sam*_*son 1 php validation laravel

我正在为 Laravel 应用程序编写一些验证规则,如果存在另一个字段,我需要忽略某些字段。我知道“有时”功能可能是最好的方法,但是如何使用数组实现该功能?

第一次尝试(没有成功,因为 Laravel 会在字段存在的任何时候进行验证):

// Device Rules
$deviceRules = [
    'devices' => 'required|array|min:1',
    'devices.*.id' => 'integer',
    'devices.*.network' => 'max:255',

    'devices.*.code' => "required_without:devices.*.id|max:255|unique:devices,code",
    'devices.*.make_id' => 'required_without:devices.*.id|in:' . Make::getImplodedKeys(),
    'devices.*.model_id' => 'required_without:devices.*.id|in:' . DeviceModel::getImplodedKeys(),

    'devices.*.fault_id' => 'required|array|min:1',
    'devices.*.fault_id.*' => 'in:' . Fault::getImplodedKeys(),
    'devices.*.warranty' => 'required|boolean'
]
Run Code Online (Sandbox Code Playgroud)

所以我第二次尝试使用“sometimes()”(但我不太知道如何实现这一点。):

public function rules()
{
    // Device Rules
    $deviceRules = [
        'devices' => 'required|array|min:1',
        'devices.*.id' => 'integer',
        'devices.*.network' => 'max:255',

        'devices.*.fault_id' => 'required|array|min:1',
        'devices.*.fault_id.*' => 'in:' . Fault::getImplodedKeys(),
        'devices.*.warranty' => 'required|boolean'
    ];

    return $deviceRules ;
}

protected function getValidatorInstance(){
    $validator = parent::getValidatorInstance();

    $validator->sometimes('devices.*.code', 'required|max:255|unique:devices,code', function($input)
    {
        return isset($input->devices.*.id);
    });

    $validator->sometimes('devices.*.make_id', 'required|in:' . Make::getImplodedKeys(), function($input)
    {
        return isset($input->devices.*.id);
    });

    $validator->sometimes('devices.*.model_id', 'required|in:' . DeviceModel::getImplodedKeys(), function($input)
    {
        return isset($input->devices.*.id);
    });

    return $validator;
}
Run Code Online (Sandbox Code Playgroud)

我还没有测试过这个,因为显然它不起作用,return isset($input->devices.*.id);毫无疑问会抛出错误。我怎样才能正确实施这一点?

Sam*_*son 5

我找到了自己的解决方案

见下文:

// Device Rules
$deviceRules = [
    'devices' => 'required|array|min:1',
    'devices.*.id' => 'integer',
    'devices.*.network' => 'max:255'
];

foreach($this['devices'] as $index => $device){
    if(!isset($device['id'])){

        $additionalDeviceRules = [
            'devices.' .$index. '.code' => 'required|max:255|unique:devices,code',
            'devices.' .$index. '.make_id' => 'required|in:' . Make::getImplodedKeys(),
            'devices.' .$index. '.model_id' => 'required|in:' . DeviceModel::getImplodedKeys(),

            'devices.' .$index. '.fault_id' => 'required|array|min:1',
            'devices.' .$index. '.fault_id.*' => 'in:' . Fault::getImplodedKeys(),
            'devices.' .$index. '.warranty' => 'required|boolean'
        ];

        $deviceRules = array_merge($deviceRules, $additionalDeviceRules);
    }
}
Run Code Online (Sandbox Code Playgroud)

*基本上,您需要指定索引 id,而不是使用占位符索引。然后 Laravel 可以解析索引 id 并有条件地应用您的规则。