如何在laravel验证中验证多个电子邮件?

11

我已经对 Laravel 中的变量进行了全部验证,但是对于电子邮件,我遇到了一个简单的问题。

根据 Laravel 文档,

'email' => 'required|email'

我知道这只是针对一个电子邮件地址而不是多个地址。

email=abc@xyz.com,xyz@abc.com, def@ghi,com

当我发送电子邮件数组时,仍然收到电子邮件无效的错误消息。 我已经尝试了更多的操作,

'email' => 'required|email|array'

但我仍然遇到了错误。有没有人可以帮忙。

谢谢。

6个回答

22

您需要编写自定义验证器,该验证器将手动验证数组中的每个电子邮件。在 Laravel 5 请求中,您可以像这样操作:

public function __construct() {
    Validator::extend("emails", function($attribute, $value, $parameters) {
        $rules = [
            'email' => 'required|email',
        ];
        foreach ($value as $email) {
            $data = [
                'email' => $email
            ];
            $validator = Validator::make($data, $rules);
            if ($validator->fails()) {
                return false;
            }
        }
        return true;
    });
}

public function rules() {
    return [
        'email' => 'required|emails'
    ];
}

2
为了扩展这个答案,请记得在您的validation.php语言文件中添加自定义验证消息。 - chifliiiii
1
此外,文档建议将其放置在\App\Providers\AppServiceProvider::boot中。 - mpen
1
从Laravel 5.6开始,您不需要这样做。请参阅我的答案:https://dev59.com/L10b5IYBdhLWcg3wOvCd#53271104 - Julian

13
在5.6版本或更高版本中,您可以将验证规则定义为以下形式:

'email.*' => 'required|email'

这将期望email键是有效电子邮件地址的数组。

11

我们可以在不使用自定义验证的情况下实现这一点,我们可以重写一个名为prepareForValidation的方法

protected function prepareForValidation() 
{
   //Here email we are reciving as comma seperated so we make it array
   $this->merge(['email' => explode(',', rtrim($this->email, ','))]);
}

然后上述函数将自动调用并将电子邮件地址转换为数组,之后使用数组验证规则。

public function rules()
 {
     return [
        'email.*' => 'required|email'
     ];
 }

我喜欢这个解决方案,但是我不得不在explode调用中包装array_filter以避免传递一个只有空字符串的单值数组。此外,由于现在失败的是例如foobar.0而不仅仅是foobar,所以这给我显示验证消息带来了一些麻烦。 - Illya Moskvin
您可以使用公共函数messages()来格式化消息,例如'foobar.*.required' => '电子邮件格式不正确'。这样,foobar.0就不会出现了。 - Elby
这样做更好,更符合"Laravel"的风格。$this->merge(['email' => array_map('trim', explode(',', $this->email))]); - Nilpo

2

1
仅在存在多个输入时相关。 - jezmck

2

我是这样做的。对我来说工作得很好。 如果电子邮件或电子邮件(email1@gmail.com,email2@yahoo.com,email3@gmail.com)来自以下表单,则自定义验证器将起作用。这需要添加到- AppServiceProvider.php-文件中。新规则为-'emails'。

    /**
     * emails
     * Note: this validates multiple emails in coma separated string.
     */
    Validator::extend('emails', function ($attribute, $value, $parameters, $validator) {
        $emails = explode(",", $value);
        foreach ($emails as $k => $v) {
            if (isset($v) && $v !== "") {
                $temp_email = trim($v);
                if (!filter_var($temp_email, FILTER_VALIDATE_EMAIL)) {
                    return false;
                }
            }
        }
        return true;
    }, 'Error message - email is not in right format');

在您的控制器中,可以像这样使用:

    $this->validate($request, [
        'email_txt_area' => 'emails',
    ]);

1

如果您不想因为一个规则而覆盖prepareForValidation,这里有另一种使用闭包的方法:

$rules = [
    'name'  => 'required|string|max:255',
    'email' => [
        'required',
        function ($attribute, $value, $fail) {
            $emails = array_map('trim', explode(',', $value));
            $validator = Validator::make(['emails' => $emails], ['emails.*' => 'required|email']);
            if ($validator->fails()) {
                $fail('All email addresses must be valid.');
            }
        },
    ],
];

已在Laravel 9.x上进行测试


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