Laravel验证规则如果另一个字段数组中存在值

时间:2017-03-31 18:42:10

标签: php laravel laravel-5 laravel-5.4 laravel-validation

我在Laravel 5.4中工作,我有一个稍微具体的验证规则需要,但我认为这应该很容易实现,而不必扩展类。只是不确定如何使这项工作..

如果'music_instrument'数组包含program,我想要强制'Music'表单字段。

我找到了这个帖子How to set require if value is chosen in another multiple choice field in validation of laravel?,但它不是一个解决方案(因为它从来没有得到解决)并且它不起作用的原因是因为提交的数组索引不是常量(在索引提交结果时未考虑选中的复选框...)

我的情况如下:

<form action="" method="post">
    <fieldset>

        <input name="program[]" value="Anthropology" type="checkbox">Anthropology
        <input name="program[]" value="Biology"      type="checkbox">Biology
        <input name="program[]" value="Chemistry"    type="checkbox">Chemistry
        <input name="program[]" value="Music"        type="checkbox">Music
        <input name="program[]" value="Philosophy"   type="checkbox">Philosophy
        <input name="program[]" value="Zombies"      type="checkbox">Zombies

        <input name="music_instrument" type="text" value"">

        <button type="submit">Submit</button>

    </fieldset>
</form>

如果我从复选框列表中选择一些选项,我可能会在$request值中显示此结果

[program] => Array
    (
        [0] => Anthropology
        [1] => Biology
        [2] => Music
        [3] => Philosophy
    )

[music_instrument] => 'Guitar'

在这里查看验证规则:https://laravel.com/docs/5.4/validation#available-validation-rules我认为像他这样的东西应该有效,但我实际上什么都没有:

  $validator = Validator::make($request->all(),[
        'program'           => 'required',
        'music_instrument'  => 'required_if:program,in:Music'
  ]);

我希望这也能奏效,但没有运气:

'music_instrument'  => 'required_if:program,in_array:Music',

思考?建议?

谢谢!

5 个答案:

答案 0 :(得分:12)

没有尝试过,但是在一般的数组字段中,你通常会这样写:program.*,所以这样的事情可能会起作用:

  $validator = Validator::make($request->all(),[
        'program'           => 'required',
        'music_instrument'  => 'required_if:program.*,in:Music'
  ]);

如果它不起作用,显然你也可以用其他方式做到这一点,例如:

$rules = ['program' => 'required'];

if (in_array('Music', $request->input('program', []))) {
    $rules['music_instrument'] = 'required';
}

$validator = Validator::make($request->all(), $rules);

答案 1 :(得分:2)

我遇到类似问题的方法是在我的Controller类中创建一个私有函数,如果它返回true,则使用三元表达式添加必需的字段。

我有大约20个字段,在这种情况下有一个复选框来启用输入字段,因此相比之下它可能有点过分,但随着您的需求增长,它可能会有所帮助。

/**
 * Check if the parameterized value is in the submitted list of programs
 *  
 * @param Request $request
 * @param string $value
 */
private function _checkProgram(Request $request, string $value)
{
    if ($request->has('program')) {
        return in_array($value, $request->input('program'));
    }

    return false;
}

使用此功能,如果您的其他程序还有其他字段,则可以应用相同的逻辑。

然后在商店功能:

public function store(Request $request)
{
    $this->validate(request(), [
    // ... your other validation here
    'music_instrument'  => ''.($this->_checkProgram($request, 'music') ? 'required' : '').'',
    // or if you have some other validation like max value, just remember to add the |-delimiter:
    'music_instrument'  => 'max:64'.($this->_checkProgram($request, 'music') ? '|required' : '').'',
    ]);

    // rest of your store function
}

答案 2 :(得分:2)

您可以像这样创建一个名为required_if_array_contains的新自定义规则...

在app / Providers / CustomValidatorProvider.php中添加一个新的私有函数:

/**
 * A version of required_if that works for groups of checkboxes and multi-selects
 */
private function required_if_array_contains(): void
{
    $this->app['validator']->extend('required_if_array_contains',
        function ($attribute, $value, $parameters, Validator $validator){

            // The first item in the array of parameters is the field that we take the value from
            $valueField = array_shift($parameters);

            $valueFieldValues = Input::get($valueField);

            if (is_null($valueFieldValues)) {
                return true;
            }

            foreach ($parameters as $parameter) {
                if (in_array($parameter, $valueFieldValues) && strlen(trim($value)) == 0) {
                    // As soon as we find one of the parameters has been selected, we reject if field is empty

                    $validator->addReplacer('required_if_array_contains', function($message) use ($parameter) {
                        return str_replace(':value', $parameter, $message);
                    });

                    return false;
                }
            }

            // If we've managed to get this far, none of the parameters were selected so it must be valid
            return true;
        });
}

也不要忘记在CustomValidatorProvider.php的顶部检查use语句,以便我们将Validator用作新方法的参数:

...

use Illuminate\Validation\Validator;

然后在CustomValidatorProvider.php的boot()方法中调用新的私有方法:

public function boot()
{
    ...

    $this->required_if_array_contains();
}

然后教Laravel以一种人类友好的方式编写验证消息,方法是在resources / lang / en / validation.php中向数组添加新项:

return [
    ...

    'required_if_array_contains' => ':attribute must be provided when &quot;:value&quot; is selected.',
]

现在您可以编写如下验证规则:

public function rules()
{
    return [
        "animals": "required",
        "animals-other": "required_if_array_contains:animals,other-mamal,other-reptile",
    ];
}

在上面的示例中,animals是一组复选框,而animals-other是文本输入,仅在选中other-mamalother-reptile值时才需要。

这对于启用了多重选择的选择输入或在请求中的一个输入中导致值数组的任何输入也适用。

答案 3 :(得分:2)

我知道这篇文章较旧,但如果有人再次遇到这个问题。

$validator = Validator::make($request->all(),[
    'program' => 'required',
    'music_instrument'  => 'required_if:program,Music,other values'
]);

答案 4 :(得分:0)

这是我的代码,用于解决Laravel 6验证规则这类问题

我尝试使用上面的代码

public function rules() 
{
    return [
      "some_array_field.*" => ["required", "integer", "in:1,2,4,5"],
      "another_field" => ["nullable", "required_if:operacao.*,in:1"],
    ];
}

我需要在 some_array_field 的值为1时,必须验证 other_field ,否则为空。 使用上述代码,即使使用required_if:operacao.*,1

也无法正常工作

如果我将 another_field 的规则更改为required_if:operacao.0,1,但前提是要查找的值在索引0中,则当顺序更改时,验证将失败

所以,我决定使用自定义的关闭函数

这是该示例的最终代码,对我来说很好。

public function rules() 
{
    return [
      "some_array_field.*" => ["required", "integer", "in:1,2,4,5"],
      "another_field" => [
          "nullable",
          Rule::requiredIf (
              function () {
                  return in_array(1, (array)$this->request->get("some_array_field"));
              }
          ),
        ]
    ];
}

我希望也能解决您的麻烦!