Laravel 9基于用户角色的条件验证最优实现方案咨询
Laravel 9 基于用户角色的条件验证最优实现
需求梳理
- 所有用户通用必填验证字段:
name:必填email:必填、字符串、邮箱格式、最大255字符、用户表唯一phone:必填、最大22字符municipality_of_origin:必填
- 角色为
business时,额外必填:company_name、company_title - 角色为
worker时,额外必填:designation、salary
你的现有尝试
你曾尝试通过条件判断补充验证规则,但逻辑分散且未利用Laravel的FormRequest特性:
// 基础验证 $this->validate($this->_request, [ 'name' => 'required', 'email' => ['required', 'string', 'email', 'max:255', 'unique:users'], 'phone' => ['required', 'max:22'], 'municipality_of_origin' => 'required', ]); // 角色相关验证逻辑(未整合到统一验证流程) if($role == 'business'){ 'company_name' => 'required', 'company_title' => 'required', } if($role == 'worker'){ 'designation' => 'required', 'salary' => 'required', } // 数据创建逻辑 $data = $request->safe()->only('name', 'email', 'phone', 'municipality_of_origin'); $user = User::create($data); if($role == 'business'){ $business_user = $request->safe()->only('company_name', 'company_title'); $business_user['user_id'] = $user->id; $user->business->create($business_user); // 此处存在调用错误,应使用business()方法 }
你尝试用FormRequest实现时,因错误使用$this->attributes导致无法正确获取请求参数,出现返回null的问题。
最优实现:使用FormRequest统一管理验证
FormRequest是Laravel中处理请求验证的标准方式,能将验证逻辑从控制器中分离,代码更清晰可维护。
1. 创建FormRequest类
执行Artisan命令生成请求类:
php artisan make:request StoreUserRequest
2. 编写验证规则
在app/Http/Requests/StoreUserRequest.php中编写如下代码:
<?php namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; class StoreUserRequest extends FormRequest { /** * 允许所有用户发起此请求(可根据你的权限逻辑调整) */ public function authorize(): bool { return true; } /** * 定义验证规则 */ public function rules(): array { // 通用规则 $rules = [ 'name' => 'required', 'email' => ['required', 'string', 'email', 'max:255', 'unique:users'], 'phone' => ['required', 'max:22'], 'municipality_of_origin' => 'required', 'role' => ['required', 'in:business,worker'], // 先限制角色只能是指定值 ]; // 根据角色动态添加规则 $role = $this->input('role'); if ($role === 'business') { $rules['company_name'] = 'required'; $rules['company_title'] = 'required'; } elseif ($role === 'worker') { $rules['designation'] = 'required'; $rules['salary'] = 'required'; } return $rules; } /** * 自定义错误提示(可选) */ public function messages(): array { return [ 'company_name.required' => '企业名称不能为空', 'company_title.required' => '企业职位不能为空', 'designation.required' => '职位名称不能为空', 'salary.required' => '薪资不能为空', 'role.in' => '角色只能是企业用户或普通员工', ]; } }
3. 在控制器中使用FormRequest
修改控制器的store方法,直接注入StoreUserRequest,Laravel会自动完成验证:
<?php namespace App\Http\Controllers; use App\Http\Requests\StoreUserRequest; use App\Models\User; class UserController extends Controller { public function store(StoreUserRequest $request) { // 获取通过验证的安全数据 $userData = $request->validated(); // 提取用户基础字段创建用户 $user = User::create([ 'name' => $userData['name'], 'email' => $userData['email'], 'phone' => $userData['phone'], 'municipality_of_origin' => $userData['municipality_of_origin'], ]); // 根据角色创建关联数据 $role = $userData['role']; if ($role === 'business') { // 调用关系方法business()而非属性business,确保创建新关联 $user->business()->create([ 'company_name' => $userData['company_name'], 'company_title' => $userData['company_title'], ]); } elseif ($role === 'worker') { // 假设Worker模型与User是hasOne关系,替换为你的实际关系方法 $user->worker()->create([ 'designation' => $userData['designation'], 'salary' => $userData['salary'], ]); } return redirect()->route('users.index')->with('success', '用户创建成功'); } }
问题说明:关于$this->attributes的错误使用
你之前在FormRequest中使用$this->attributes->has()是错误的,$this->attributes并非用于获取请求参数的属性。在FormRequest中,获取请求参数应使用:
$this->input('key'):获取指定参数值$this->has('key'):检查参数是否存在$this->all():获取所有请求参数
内容的提问来源于stack exchange,提问作者Inaam ul haq
相关产品推荐
相关产品推荐

