Laravel控制器中非重复请求验证的解决方案?

时间:2019-03-10 01:10:58

标签: php laravel

在我的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),并且这种重复变得太过重复了。我正在尝试遵循DRY原则(请不要重复自己),并且希望您提出有关如何防止用户验证重复的解决方案。解决方案可以在PHP / Laravel中进行,但是我在Laravel项目中工作。

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

1 个答案:

答案 0 :(得分:3)

您应该旨在清楚地分离应用程序的各个组件,这意味着验证应该是单个过程,而不是多个分散的过程。您当前的方法-使用Laravel验证程序验证一些输入,然后手动验证其余输入-并不理想。

理想的方法是使用Laravel验证程序来验证输入的 all ,包括状态。 Form Requests可以帮助您实现其他功能,Rule Objects可以使您在多个控制器上实施更高级的验证重复使用,http://localhost/api/query/GetNameList则可以让您实现属性的自定义验证逻辑。

您的代码执行以下操作:

  1. 检查用户是否存在
  2. 检查评估是否存在
  3. 检查用户是否属于公司
  4. 检查用户是否为候选人
  5. 检查用户是否已经进行评估

每个都可以实现为自定义规则,然后您可以创建一个看起来像这样的表单请求:

/**
 * Get the validation rules that apply to scheduling an Assessment.
 *
 * @return array
 */
public function rules(): array
{
    return [
        'assessment_id' => 'required|exists:assessments',
        'user_id' => ['required', 'exists:users', new BelongsToCompany, new IsCandidate],
        'due_date' => 'required|date',
    ];
}

然后,对于更复杂的验证(例如,验证用户还没有需要2个输入值的评估),您可以拥有一个规则,您可以明确地传递附加值您可以使用withValidator来扩展验证器-文档中对此进行了介绍。

传入附加值:

/**
 * Get the validation rules that apply to scheduling an Assessment.
 *
 * @return array
 */
public function rules(): array
{
    return [
        'assessment_id' => ['required', 'exists:assessments', new AssessmentAvailable(request()->input('user_id'))],
        'user_id' => ['required', 'exists:users', new BelongsToCompany, new IsCandidate],
        'due_date' => 'required|date',
    ];
}

扩展验证器:

public function rules(): array
{
    // ...
}

/**
 * Validates whether or not an assessment is available for the User.
 *
 * @param \Illuminate\Validation\Validator $validator
 *
 * @return void
 */
public function withValidator($validator)
{
    $validator->after(function ($validator) {
        $user = User::findOrFail($this->input('user_id'));
        $assessment = Assessment::findOrFail($this->input('assessment_id'));

        if ($user->hasAssessment($assessment)) {
            $validator->errors()->add('assessment_id', 'The user already has this assessment.');
        }
    });
}

这种方法使您易于重用验证逻辑以及Laravel验证系统的全部功能,包括用户的输入错误。