Laravel有时验证规则

14

如果密码字段存在,我希望验证它。我想允许某人编辑用户,他们可能希望更改用户的密码,也可能不希望更改。所以我认为可以使用Laravel的验证规则来实现这一点,具体地说是使用“sometimes”规则。我的规则如下:

$this->validate($request, [
    'password' => 'sometimes|required|min:8',
]);

这只是为了示例而简化的内容,通常对于其他字段会有其他规则,并且密码会有更严格的规定。我希望只有当传递的数据中存在密码字段时才应用min:8规则,但如果我将密码字段留空,则会出现验证错误,提示需要填写密码字段。

我不确定在文档中哪里理解有误。如果表单输入为空,我是否需要在验证之前手动删除密码字段?

$data = $request->all();

if ('' === $data['password']) {
    unset($data['password'])
}

...然后将数组传递到验证器中。我认为这很有道理,但我需要确认我理解得正确。谢谢提前。


从文档中,这就是我所理解的。因此,除非有人告诉你其他情况,否则你基本上可以开始了。 - Nabin Kunwar
似乎如果您删除必需的规则,则可以像这样正常工作:'sometimes | min:8 .....",但是文档并没有真正解释清楚。 - Steven1978
是的,这也是我最初想到的,然后再次检查了文档。 :D - Nabin Kunwar
我看到一条评论说要这样做,所以我就这样做了,然后评论消失了,那是你的评论吗? - Steven1978
是的,那是我。无论如何,很高兴能够帮助。 - Nabin Kunwar
10个回答

18

文档不够明确,但是去掉 required 属性可以让它工作。

$this->validate($request, [
    'password' => 'sometimes|min:8',
]);

看起来很明显,但文档将你引导到了错误的解决方案。感谢您的帮助 :)。 - Steven1978
是的,我在代码上做了它,但看到文档后感到困惑。很高兴能帮忙 :) - Nabin Kunwar
我理解得对吗?有时规则意味着输入是可选的吗? - TheCrazyProfessor
在某些情况下,您可能希望仅针对输入数组中存在的字段运行验证检查。 - Peter Chaula

17

我认为我们应该告诉 Laravel,如果密码不为空,则设置规则,否则不执行任何操作。

$this->validate($request, [
  'password' => $request->password != null ?'sometimes|required|min:8': ''
]);

在上面的示例中,只有当密码字段出现在$data数组中时,它才会被验证。 - Nabin Kunwar
@nbin 你能引用一下吗? - Basheer Kharoti
我确实在文档中读到过这个,但我觉得手动从数组中删除某些东西并不是一个好的做法。此外,您无法使用自定义请求进行验证规则。 - Steven1978
@nbin 那么 $data 实际上是什么?一个数据数组,所以请求中包含所有这些东西。 - Basheer Kharoti
@Steven1978 我同意使用“自定义请求”无法解决问题,但我没有看到其他的解决方法。 - Basheer Kharoti
@BasheerAhmed $data是一个变量。我的意思是,文档说如果post数组不包含$password字段,它就不会验证它。 - Nabin Kunwar

7

如果密码字段存在,我想验证它。

为了实现这个目标,你可以使用验证系统中的“nullable”规则。

例如:

$this->validate($request, [
    'password' => 'sometimes|nullable|min:8',
]);

更多信息请查看“可选字段说明”下的https://laravel.com/docs/5.6/validation部分。


5
这是一个老问题,但是上面的答案有很多混淆。这是目前谷歌搜索“sometimes validation rule”的第一个结果,所以我希望能为其他谷歌用户澄清一些事情:

sometimes规则的工作方式如下:

  • 如果字段存在于请求中,请使用其余规则进行验证;
  • 如果该字段不存在,则不执行任何操作。

请注意,不存在意味着该字段从未被提交isset($_POST['password']) === false),它与提交空字符串、null或0值的字段不同——因此,只有当表单根本没有密码字段,或者禁用了密码字段以使其永远不会被提交时,'sometimes|required|min:8'才会起作用。

如果密码字段存在,只是留空,然后提交表单,我们仍将得到'password' => null,对于sometimes来说,它意味着它存在,因此将应用其余规则(由于必填字段不能为空,因此请求将失败)。

OP真正需要的是:

'password' => 'nullable|min:8',

假设请求中始终存在密码字段,只是有时其值可能为空。


3

我认为,只有在用户提供旧密码的情况下,允许用户更改密码是更加安全的。

如果允许已连接的用户在不提供旧密码的情况下更改密码,可能会存在安全问题。

以下是我通常使用Laravel允许用户更改密码的方法:

 $this->validate($request, [
            'user.old_password' => [],
            'user.password' => [
                'required_with:user.old_password',
                'min:6',
                'confirmed',
                'regex:/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*([-+_!@#$%^&*.,;?])).+$/',
                'different:user.old_password'
            ],
            'user.password_confirmation' => ['required_with:user.password'],
        ]);

我们不验证旧密码,因为数据库会代替我们进行验证。但是,仅当提供旧密码时,我才会验证新密码。


2
在编辑模式下,您可以使用例如“********”填写密码字段,在更新模式下可以进行如下验证。
$this->validate($request, [
    'password' => 'required|min:8',
]);

在控制器中检查 $data['password']='********',查找旧密码并进行相关操作。

$data['password']='old password in db'

如果$data['password']!='********',则更新密码


2

作为所选答案的备选方案,你可以使用:

    $this->validate($request, [
       'password' => 'nullable|min:8',
    ]);

1
这种记号会很有用:
$this->validate($request,[
        'password' => Rule::when(request()->has('password'), ['required','min:6']),
    ]);

使用 Illuminate\Validation\Rule 的技术


0

如果存在值,则会检查最小长度。它在 Laravel 6.18 中可以100%正常工作。

$this->validate($request,[
            'user_id' => 'sometimes|nullable|min:5'
        ]);

-1

Laravel 有时候验证规则及其功能:

accepted 验证字段必须是 yes、on、1 或 true。这对于验证“服务条款”接受非常有用。

active_url 验证字段必须具有有效的 A 或 AAAA 记录,根据 dns_get_record PHP 函数。

after:date 验证字段必须是给定日期之后的值。日期将传递到 strtotime PHP 函数中: 'start_date' => 'required|date|after:tomorrow' 您可以指定另一个字段来与日期进行比较,而不是传递要由 strtotime 评估的日期字符串: 'finish_date' => 'required|date|after:start_date'

after_or_equal:date 验证字段必须是给定日期之后或等于该日期的值。有关详细信息,请参见 after 规则。

alpha 验证字段必须完全是字母字符。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接