在我的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语句)。
您应该明确区分应用程序的各个组件,这意味着验证应该是单个进程而不是多个分段进程。您当前的方法 - 使用Laravel验证器验证某些输入,然后手动验证其余输入 - 不太理想。
理想的方法是使用Laravel Validator验证所有输入,包括状态。还有其他一些功能可以帮助你,Form Requests允许你在多个控制器上实现更高级的验证和重用验证,并且有Rule Objects允许你为属性实现自定义验证逻辑。
您的代码执行以下操作:
其中每个都可以实现为自定义规则,然后您可以创建一个单独的表单请求,如下所示:
/**
* 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验证系统的全部功能,包括用户的输入错误。