Laravel 8邮箱唯一性验证规则失效,$validator->fails()始终返回false
问题
我需要插入客户数据,要求customer_email字段唯一。以下是MySQL表结构、Customer模型及控制器中的验证代码,但插入重复邮箱时$validator->fails()始终返回false(即验证未检测到重复),请问遗漏了什么?
MySQL表结构
CREATE TABLE IF NOT EXISTS `customers` ( `id` int NOT NULL AUTO_INCREMENT, `customer_name` varchar(20) NOT NULL, `customer_address` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `customer_email` varchar(20) NOT NULL, `customer_city` varchar(50) NOT NULL, `post_code` varchar(20) NOT NULL, `customer_phone` int NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NULL DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `customer_email` (`customer_email`) ) ENGINE=MyISAM AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; COMMIT;
Customer模型
class Customer extends Model { protected $table="customers"; protected $fillable = ['customer_name', 'customer_email','customer_address', 'customer_city','customer_postcode']; }
控制器代码
$validator = Validator::make($request->all(), [ 'customer_name' => 'required', 'customer_address' => 'required', 'customer_email' => "required|unique:customers", 'customer_city' => 'required', 'post_code' => 'required', 'customer_phone' => 'required', ]); var_dump($validator->fails());
问题排查与解决
1. 模型可填充字段与请求/表字段不匹配
模型$fillable中定义的是customer_postcode,但数据库表字段是post_code,控制器验证的也是post_code。这会导致插入数据时post_code字段无法被赋值,同时customer_phone也未加入可填充列表,需修正模型:
protected $fillable = ['customer_name', 'customer_email','customer_address', 'customer_city','post_code', 'customer_phone'];
2. unique验证规则的大小写敏感性问题
你的表使用utf8mb4_0900_ai_ci字符集(大小写不敏感),但Laravel的unique验证默认区分大小写。比如数据库已有test@example.com,请求传入Test@Example.com时,数据库唯一约束会拦截,但Laravel验证会判定为不同值,导致fails()返回false。
解决方法:添加lowercase过滤器,统一转换为小写后验证:
'customer_email' => "required|email|lowercase|unique:customers,customer_email",
或者使用规则类实现大小写不敏感匹配:
use Illuminate\Validation\Rule; // 验证规则中替换为 'customer_email' => [ 'required', 'email', Rule::unique('customers')->whereRaw('LOWER(customer_email) = LOWER(?)', [$request->customer_email]) ],
3. 数据库字段类型错误
customer_phone定义为int类型,但11位手机号会超出MySQLint的最大值(2147483647),导致插入失败,建议修改为字符串类型:
ALTER TABLE `customers` MODIFY COLUMN `customer_phone` varchar(20) NOT NULL;
4. 检查请求参数一致性
通过dd($request->all())确认传入的参数名是否与验证规则一致,比如是否把customer_email误写成email,参数名不匹配会导致验证规则失效。
内容的提问来源于stack exchange,提问作者Muntashir Are Rahi
相关产品推荐
相关产品推荐

