验证输入的自定义规则不包含坏词

Posted

技术标签:

【中文标题】验证输入的自定义规则不包含坏词【英文标题】:custom rule for validate input does not contain bad words 【发布时间】:2021-08-19 08:21:33 【问题描述】:

我有一个包含不同表格的 API,例如:posts、questions、cmets 和 ..,我不想让用户使用坏词来填写这些表格的字段并在使用这些词时向他们显示错误。

所以我搜索并写了这个 FormRequest 来验证类别描述:

 public function rules()
        Validator::extend('not_contains', function($attribute, $value, $parameters)
            // Banned words
            $words = array('f***', 's***' , 'a****' , 'b***');
                foreach ($words as $word) 
                    if (stripos($value, $word) !== false) 
                        return false;
                    
                
            return true;
        );


        $rules = [
            'description'=>['required','max:500' ,'not_contains'],
        ];

        if ('PUT' === $this->method()) 
            $rules['title'] = 'required|unique:categories,id,' . $this->route('category_id');
        
        else
            $rules['title'] = 'required|unique:categories|';
        

            return $rules;
    



它有效,但我不想在任何 formRequest 中使用这个 not_contains 代码,所以我创建了这个自定义规则:

class CheckBadWords implements Rule

    /**
     * Create a new rule instance.
     *
     * @return void
     */
    public function __construct()
    
        //
    

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    
        Validator::extend('bad_words', function($attribute, $value, $parameters)
            // Banned words
            $words = array('f***', 's***' , 'a****' , 'b***');
            foreach ($words as $word) 
                if (stripos($value, $word) !== false) 
                    return false;
                
            
            return true;
        );
    

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    
        return 'bad word used!';
    



在表单请求中,我将其添加到 $rules :

   $rules = [
            'description'=>['required','max:500' ,new checkBadWords()],
        ];

所以当我发送请求时,此规则适用于每个包含并给出验证错误:bad word used! 即使对于不包含这些坏词的内容

【问题讨论】:

正在使用 php 8 吗? 不,我使用 php 7.4.3 我已经更新了答案 有一些包可以满足这个用例,this one looks reasonable 虽然有一段时间没有更新。您需要的大部分内容已经完成,但如果您真的需要,您可以为 repo 完成。 【参考方案1】:

将您的规则类 pass() 方法更改为

public function passes($attribute, $value)

    $words = array('f***', 's***' , 'a****' , 'b***');

    foreach ($words as $word) 
        if (stripos($value, $word) !== false) 
            return false;
        
    

    return true;

【讨论】:

我试过了,但有区别,当我使用你的代码时,用户可以通过将单词粘贴到其他单词中来绕过规则:fu%ckf*ck,但是我的代码识别了/跨度> 【参考方案2】:

您可以编写如下自定义规则

class CheckBadWords implements Rule

    /**
     * Create a new rule instance.
     *
     * @return void
     */
    public function __construct()
    
        //
    

    /**
     * Determine if the validation rule passes.
     *
     * @param  string $attribute
     * @param  mixed $value
     * @return bool
     */
    public function passes($attribute, $value)
    
        $words = array('f***', 's***' , 'a****' , 'b***');
        $wordFound = false;
        foreach ($words as $badword) 

            if (str_contains($value, $badword)) 
                $wordFound = true;
                break;
            


        

        if ($wordFound) 

            return false;
        

        return true;

    


/**
 * Get the validation error message.
 *
 * @return string
 */
public function message()

    return 'bad word used!';


如果您使用的不是最新版本的 php,请将 str_contains 更改为 stripos

【讨论】:

以上是关于验证输入的自定义规则不包含坏词的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 中正则表达式规则的自定义验证消息?

使用带有附加参数的自定义规则验证 Laravel 中的数组

使用列名和过滤器检查存在的自定义验证规则

如何使唯一数组的自定义验证规则依赖于其他字段 laravel

Laravel 验证规则的自定义错误消息:维度

如何根据 Angular 2 中的自定义验证规则显示错误消息?