You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Laravel的notIn验证规则实现大小写不敏感?

解决Laravel中notIn验证规则区分大小写的问题

这个问题很常见,Laravel默认的Rule::notIn()确实是严格区分大小写的,导致像"Apple"和"apple"这类值会被判定为不同项,没法阻止重复。这里有几个实用的解决方案:

方案一:使用闭包自定义验证逻辑

直接在验证规则里写个闭包,把输入值和已有选项都转换成统一大小写(比如小写)再做判断,这样就能忽略大小写差异了:

$this->validate(request(), [
    'choice' => [
        'required',
        function ($attribute, $value, $fail) use ($choices) {
            // 将输入值和已有选项全部转为小写,同时去除前后空格避免伪重复
            $normalizedValue = strtolower(trim($value));
            $normalizedChoices = array_map(fn($item) => strtolower(trim($item)), $choices);
            
            if (in_array($normalizedValue, $normalizedChoices)) {
                $fail('The :attribute has already been added (case-insensitive duplicate).');
            }
        }
    ]
]);

方案二:封装成可复用的自定义验证规则

如果这个验证逻辑在多个地方用到,把它封装成自定义规则会更优雅,方便后续复用:

  1. 首先创建规则类:
// app/Rules/UniqueCaseInsensitiveInArray.php
namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class UniqueCaseInsensitiveInArray implements Rule
{
    protected $existingItems;

    public function __construct(array $existingItems)
    {
        $this->existingItems = $existingItems;
    }

    public function passes($attribute, $value)
    {
        $normalizedValue = strtolower(trim($value));
        $normalizedItems = array_map(fn($item) => strtolower(trim($item)), $this->existingItems);
        
        return !in_array($normalizedValue, $normalizedItems);
    }

    public function message()
    {
        return 'The :attribute already exists (case does not matter).';
    }
}
  1. 然后在验证时引入并使用这个规则:
use App\Rules\UniqueCaseInsensitiveInArray;

$this->validate(request(), [
    'choice' => [
        'required',
        new UniqueCaseInsensitiveInArray($choices)
    ]
]);

方案三:利用Rule::notIn的transform方法简化写法

Laravel的Rule::notIn()支持链式调用transform()方法来预处理输入值,配合提前标准化的已有选项数组,能写出更简洁的代码:

// 先将数据库取出的选项数组标准化
$normalizedChoices = array_map(fn($item) => strtolower(trim($item)), $choices);

$this->validate(request(), [
    'choice' => [
        'required',
        Rule::notIn($normalizedChoices)->transform(fn($value) => strtolower(trim($value)))
    ]
]);

内容的提问来源于stack exchange,提问作者Mac

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:52:12