在我的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>
答案 0 :(得分:3)
您应该旨在清楚地分离应用程序的各个组件,这意味着验证应该是单个过程,而不是多个分散的过程。您当前的方法-使用Laravel验证程序验证一些输入,然后手动验证其余输入-并不理想。
理想的方法是使用Laravel验证程序来验证输入的 all ,包括状态。 Form Requests可以帮助您实现其他功能,Rule Objects可以使您在多个控制器上实施更高级的验证和重复使用,http://localhost/api/query/GetNameList则可以让您实现属性的自定义验证逻辑。
您的代码执行以下操作:
每个都可以实现为自定义规则,然后您可以创建一个看起来像这样的表单请求:
/**
* 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验证系统的全部功能,包括用户的输入错误。