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

Laravel中如何将输入转小写并实现分类名唯一校验

解决Laravel中字段转小写存储与不区分大小写唯一约束问题

我来帮你搞定这两个问题,分步骤给你说清楚:

一、实现字段自动转小写存储

你之前尝试strtolower($kategori->nama_kategori)无效,核心原因是顺序搞反了——你得先把请求参数转成小写,再赋值给模型属性,而不是先赋值再转(那样操作的是模型里的旧值,没重新赋值回去当然不会生效)。推荐两种方案:

1. 手动处理赋值(快速直接)

直接在赋值环节对请求参数做小写转换:

$kategori = new Kategori;
$kategori->nama_kategori = strtolower($request->nama_kategori); // 先转小写再赋值给模型
$kategori->save();

2. 使用模型修改器(优雅持久)

如果希望每次给nama_kategori赋值时都自动转小写,不用重复写转换代码,可以在Kategori模型里添加修改器(Mutator),一劳永逸:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Kategori extends Model
{
    // ... 其他模型代码

    public function setNamaKategoriAttribute($value)
    {
        // 每次给该属性赋值时,自动将值转为小写后存入数据库
        $this->attributes['nama_kategori'] = strtolower($value);
    }
}

之后不管是通过请求赋值,还是直接给模型属性赋值,都会自动完成小写转换,不用再手动处理。


二、实现不区分大小写的唯一约束

要做到已有"Hello"时存储"hello"触发错误,需要同时在验证层和数据库层做处理,避免出现绕过验证直接操作数据库的漏洞:

1. 验证层添加不区分大小写的唯一规则

在你的请求验证逻辑里(比如表单请求类,或者控制器的validate方法),给nama_kategori添加带大小写忽略的唯一校验规则:

use Illuminate\Validation\Rule;

$request->validate([
    'nama_kategori' => [
        'required',
        'string',
        // 验证时将数据库字段和输入值都转成小写比对
        Rule::unique('kategori')->where(fn ($query) => $query->whereRaw('LOWER(nama_kategori) = ?', [strtolower($request->nama_kategori)]))
    ]
]);

或者用更简洁的语法:

'nama_kategori' => 'required|string|unique:kategori,nama_kategori,NULL,id,LOWER(nama_kategori),LOWER(:value)'

2. 数据库层添加不区分大小写的唯一索引

验证层只是业务逻辑校验,为了绝对保证数据唯一性,需要在数据库层面做约束,有两种方式可选:

方式一:修改字段排序规则(Collation)

把nama_kategori字段的排序规则改成不区分大小写的(比如MySQL的utf8mb4_unicode_ci,默认的utf8mb4_bin是区分大小写的)。可以通过迁移修改:

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

Schema::table('kategori', function (Blueprint $table) {
    $table->string('nama_kategori')
          ->collate('utf8mb4_unicode_ci') // 不区分大小写的排序规则
          ->unique()
          ->change();
});

执行迁移后,数据库会自动忽略大小写检查唯一性。

方式二:添加基于小写转换的函数索引

如果不想修改整个字段的排序规则,可以添加一个基于LOWER(nama_kategori)的唯一索引:

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;

Schema::table('kategori', function (Blueprint $table) {
    $table->unique(DB::raw('LOWER(nama_kategori)'), 'nama_kategori_lower_unique');
});

这样数据库会基于字段的小写值检查唯一性,同样能达到需求效果。


内容的提问来源于stack exchange,提问作者Muhammad Zainul Mutaqin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 18:57:37