Laravel控制器中手机号字段唯一验证失效问题排查
问题
需要验证users表中email和phone_no字段的唯一性,其中phone_no是将请求中的calling_code与手机号拼接后存入数据库。当前邮箱的唯一验证正常,但相同手机号(含对应区号)仍可重复提交,手机号的验证规则未生效。
原代码如下:
public function customRegistration(Request $request) { $request->validate([ 'name' => 'required', 'email' => 'required|email|unique:users', 'country' => 'required', 'phone_no' => 'required|unique:users', 'password' => 'required', ]); $data = $request->all(); $check = $this->create($data); return redirect('login')->with('message', 'Signing up successful !!!'); } public function create(array $data) { return User::create([ 'name' => $data['name'], 'email' => $data['email'], 'country' => $data['country'], 'phone_no' => $data['calling_code'] . '-' . $data['phone_no'], 'password' => Hash::make($data['password']), ]); }
原因分析
当前验证规则中,phone_no的unique:users是直接用请求里的纯手机号去匹配数据库中已经拼接了区号的phone_no字段,两者格式不一致(数据库里是区号-手机号,请求里是纯手机号),所以验证永远不会命中重复数据,导致规则失效。
解决方案
需要先将请求中的calling_code和phone_no拼接成与数据库一致的格式,再验证该值是否在users表的phone_no字段中唯一,有两种常用实现方式:
方式一:使用闭包自定义验证逻辑
修改customRegistration方法中的验证规则,通过闭包来拼接并验证:
public function customRegistration(Request $request) { $request->validate([ 'name' => 'required', 'email' => 'required|email|unique:users', 'country' => 'required', 'calling_code' => 'required', 'phone_no' => [ 'required', function ($attribute, $value, $fail) use ($request) { // 拼接成数据库存储的格式 $fullPhone = $request->calling_code . '-' . $value; // 检查数据库中是否存在该值 if (User::where('phone_no', $fullPhone)->exists()) { $fail('该手机号(含区号)已被注册'); } }, ], 'password' => 'required', ]); $data = $request->all(); $check = $this->create($data); return redirect('login')->with('message', 'Signing up successful !!!'); }
方式二:先处理请求数据再验证
先将拼接后的手机号添加到请求中,再使用unique规则验证:
public function customRegistration(Request $request) { // 拼接完整手机号并添加到请求中 $fullPhone = $request->calling_code . '-' . $request->phone_no; $request->merge(['full_phone' => $fullPhone]); $request->validate([ 'name' => 'required', 'email' => 'required|email|unique:users', 'country' => 'required', 'calling_code' => 'required', 'phone_no' => 'required', 'full_phone' => 'unique:users,phone_no', 'password' => 'required', ]); $data = $request->all(); $check = $this->create($data); return redirect('login')->with('message', 'Signing up successful !!!'); }
注意:两种方式都需要确保calling_code字段也被加入验证规则(添加required),避免因区号缺失导致拼接错误。
内容的提问来源于stack exchange,提问作者Enrich Arcane
相关产品推荐
相关产品推荐

