Laravel 验证 - 逗号分隔的字符串输入为数组

Posted

技术标签:

【中文标题】Laravel 验证 - 逗号分隔的字符串输入为数组【英文标题】:Laravel validation - comma separated string input as array 【发布时间】:2018-03-18 17:55:47 【问题描述】:

如何验证具有多个值的一个输入?我正在使用引导标签输入插件。它返回一个字段中的所有标签。我需要验证这个标签 - 唯一的。 首先,我尝试将此标签放入数组中,然后在请求中对其进行验证,但仍然没有运气。 这是我的请求代码:

public function all()

    $postData = parent::all();

    // checkbox status
    if(array_key_exists('keywords', $postData)) 

        // put keywords into array
        $keywords = explode(',', $postData['keywords']);

        $test = [];
        $i = 0;
        foreach($keywords as $keyword)
        
            $test[$i] = $keyword;
            $i++;
        
        $postData['keywords'] = $test;

    

    return $postData;



public function rules()

    $rules = [
        'title' => 'required|min:3|unique:subdomain_categories,title|unique:subdomain_keywords,keyword',
        'description' => '',
        'image' => 'required|image',
        'keywords.*' => 'min:3'
    ];

    return $rules;

但是一旦关键字变得无效,我就会收到此错误:

helpers.php 第 531 行中的错误异常: htmlentities() 期望参数 1 是字符串,给定数组。

有什么想法吗?

【问题讨论】:

【参考方案1】:

重写all() 方法来验证字段不是一个好习惯。

如果您收到一个逗号分隔的字符串,而不是您想要验证的数组,但没有可用的通用方法,请编写您自己的。

在您的App/Providers/ValidatorServiceProvider 中添加一个新的验证:

public function boot()

    Validator::extend('keywords', function ($attribute, $value, $parameters, $validator)
    
        // put keywords into array
        $keywords = explode(',', $value);

        foreach($keywords as $keyword)
        
            // do validation logic
            if(strlen($keyword) < 3)
            
                return false;
            
        

        return true;
    

现在,如果需要,您可以在任何请求上使用此验证规则,它是可重复使用的

public function rules()

    $rules = [
        'title'       => 'required|min:3|unique:subdomain_categories,title|unique:subdomain_keywords,keyword',
        'description' => 'nullable',
        'image'       => 'required|image',
        'keywords'    => 'keywords',
    ];

    return $rules;

如果验证通过并且您想让关键字在您的请求中作为数组可访问,请编写您自己的方法:

public function keywords ()

    return explode(',', $this->get('keywords'));

【讨论】:

这不起作用...这很奇怪,因为如果我尝试: dd($this->request->get('keywords'));它转储“第 1 项,第 2 项”。似乎它没有将关键字更改为数组 $this-&gt;request-&gt;get('keywords')的内容是什么,是key => value的数组还是逗号分隔的字符串【参考方案2】:

我在 5.4 上遇到了类似的逗号分隔电子邮件问题。以下是我的解决方法:

在您的请求类中,覆盖 prepareForValidation() 方法(默认情况下它什么都不做,顺便说一句),并分解您的逗号分隔字符串。

/**
 * @inheritDoc
 */
protected function prepareForValidation()

    $this->replace(['keywords' => explode(',', $this->keywords)]);

现在你可以使用 Laravel 的普通 array validation!

由于我的案例也需要对消息更加明确,因此我还添加了一些属性和消息自定义。我发了a gist,如果你也感兴趣的话

【讨论】:

这在 5.8 上似乎对我不起作用。我最终这样做了: $this->merge(['keywords' => explode(',', $this->keywords)]);【参考方案3】:

对于 Laravel 6+,有一个包可以将这些验证应用于逗号分隔的值字符串,而不是改变您的输入:

https://github.com/spatie/laravel-validation-rules#delimited

你需要install it:

composer require spatie/laravel-validation-rules

然后,您可以将其用作规则(建议使用FormRequest)。

例如,要验证所有项目都是电子邮件,不长 20 个字符且至少有 3 个,您可以使用:

use Spatie\ValidationRules\Rules\Delimited;

// ...

public function rules()

    return [
        'emails' => [(new Delimited('email|max:20'))->min(3)],
    ];

验证器的构造函数接受验证规则字符串、验证实例或数组。该规则用于验证所有单独的值;在这种情况下,'email|max:20'

【讨论】:

以上是关于Laravel 验证 - 逗号分隔的字符串输入为数组的主要内容,如果未能解决你的问题,请参考以下文章

RegEx 用于匹配除逗号分隔的数字之外的所有字符

如何使用正则表达式验证逗号分隔的字符串 [重复]

如何在 Bootstrapvalidator 中验证用逗号或半克隆分隔的多个电子邮件的电子邮件输入字段

如何为逗号分隔的字符串编写具有匹配组的正则表达式

ActionScript 3 AS3修剪逗号分隔字符串(例如,用户输入的逗号分隔关键字列表)

如何在laravel中使用逗号分隔值的列上使用'where'