Php Laravel controller中非重复请求验证的解决方案?

Php Laravel controller中非重复请求验证的解决方案?,php,laravel,Php,Laravel,在我的Laravel控制器中,我总是使用相同的验证来检查用户提交的数据是否有效 public function schedule(Request $request) { $request->validate([ 'assessment_id' => 'required|integer', 'user_id' => 'required|integer', 'due_date' => 'required|string'

在我的Laravel控制器中,我总是使用相同的验证来检查用户提交的数据是否有效

public function schedule(Request $request)
{
    $request->validate([
        'assessment_id' => 'required|integer',
        'user_id' => 'required|integer',
        'due_date' => 'required|string'
    ]);

    $assessment_id = $request->input('assessment_id');
    $user_id = $request->input('user_id');
    $due_date = $request->input('due_date');

    $staff = auth()->user();
    $company = $staff->companies()->first();
    $user = $this->staffAssessmentRepository->getUserById($user_id);
    $assessment = $this->staffAssessmentRepository->getAssessmentById($assessment_id);
    $date = Carbon::parse($due_date);

    if(!$user || !$assessment){
        return response()->json('Cannot find assessment and/or user!', 404);
    }

    if(!$company->hasUser($user)){
        return response()->json('User does not belong to this company!', 401);
    }

    if(!$user->hasRole(Role::ROLE_CANDIDATE_NAME)){
        return response()->json('User is not a candidate', 401);
    }

    if($user->hasAssessment($assessment, $company)){
        return response()->json('Candidate already has this assessment!', 401);
    }

    $user_assessment = $this->staffAssessmentRepository->scheduleUserAssessment($user, $company, $assessment, $date, $staff);

    if(!$user_assessment){
        return response()->json('Failed to create user assessment!', 500);
    }

    return response()->json($user_assessment, 201);
}
请从上面的PHP代码中查看此特定部分:

if(!$user || !$assessment){
    return response()->json('Cannot find assessment and/or user!', 404);
}

if(!$company->hasUser($user)){
    return response()->json('User does not belong to this company!', 401);
}

if(!$user->hasRole(Role::ROLE_CANDIDATE_NAME)){
    return response()->json('User is not a candidate', 401);
}

if($user->hasAssessment($assessment, $company)){
    return response()->json('Candidate already has this assessment!', 401);
}
在我的控制器方法中,我总是需要验证相同的用户案例,并多次检查它们是否失败(返回响应JSON),这会变得过于重复。我试图遵循干燥原则(不要重复你自己),并希望你的解决方案,我如何可以防止重复用户验证。解决方案可以是PHP/Laravel,但我在Laravel项目中工作


编辑:请不要说有许多
if
语句不是事实,问题不在于此。问题是相同的
if
语句在我的控制器中的多个不同方法中使用,我需要一个体系结构决策,以决定如何解耦代码,以便我的控制器可以继承相同的验证(if语句)。

您应该明确区分应用程序的各个组件,这意味着验证应该是一个单一的过程,而不是多个分散的过程。您当前的方法——使用Laravel验证器验证部分输入,然后手动验证其余输入——并不理想

理想的方法是使用Laravel验证器来验证所有输入,包括状态。还有一些其他功能可以帮助实现这一点,它们允许您跨多个控制器实现更高级的验证和重用验证,还有一些功能允许您为属性实现自定义验证逻辑

您的代码执行以下操作:

  • 检查用户是否存在
  • 检查评估是否存在
  • 检查用户是否属于该公司
  • 检查用户是否为候选人
  • 检查用户是否已进行评估
  • 其中每一项都可以实现为自定义规则,然后您可以创建一个表单请求,如下所示:

    /**
    *获取适用于计划评估的验证规则。
    *
    *@return数组
    */
    公共函数规则():数组
    {
    返回[
    “assessment_id”=>“required |存在:assessment”,
    'user_id'=>['required','exists:users',新的BelongsToCompany,新的IsCandidate],
    “到期日”=>“所需日期”,
    ];
    }
    
    然后,对于更复杂的验证(例如验证用户是否还没有需要2个输入值的评估),您可以有一个明确传递附加值的规则,或者可以使用
    withValidator
    扩展验证程序,这在文档中有介绍

    传递附加值:

    /**
    *获取适用于计划评估的验证规则。
    *
    *@return数组
    */
    公共函数规则():数组
    {
    返回[
    “评估id”=>[“必需”,“存在:评估”,新评估可用(请求()->输入('user\u id'))],
    'user_id'=>['required','exists:users',新的BelongsToCompany,新的IsCandidate],
    “到期日”=>“所需日期”,
    ];
    }
    
    扩展验证程序:

    公共函数规则():数组
    {
    // ...
    }
    /**
    *验证评估是否可供用户使用。
    *
    *@param\Lightning\Validation\Validator$Validator
    *
    *@返回无效
    */
    带验证器的公共函数($validator)
    {
    $validator->after(函数($validator){
    $user=user::findOrFail($this->input('user_id'));
    $assessment=assessment::findOrFail($this->input('assessment_id'));
    如果($user->hassassessment($assessment)){
    $validator->errors()->add('assessment_id','用户已经有此评估');
    }
    });
    }
    

    这种方法使您可以轻松地重复使用验证逻辑和Laravel验证系统的全部功能,包括用户的输入错误。

    这太棒了!感谢您的建议,我迫不及待地想尝试一下。名称“Form Request”是否意味着此验证方法只能在HTTP请求的上下文中使用?那外部的代码呢(比如说,命令行环境中的一块代码)?如果此处也需要执行相同的验证规则,该怎么办?@georaldc Form Requests专门设计用于HTTP请求时,但您可以在其他上下文中重复使用验证规则。我建议将验证规则从表单请求中提取出来,但如果愿意,可以重复使用它们。