如何在返回所有错误时使用 PHP laravel 中的公共 class 选择性地验证多个字段
How to validate multiple fields selectively using a common class in PHP laravel while returning all errors
刚开始我的第一个 PHP laravel 项目,我有这个
UserRepository.php
public function validateNewEmail(Request $request, $emailName) {
$request->validate([
$emailName => ['required', 'email', 'unique:users'],
]);
}
public function validateNewPassword(Request $request, $passwordName) {
$request->validate(
// rule
[
$passwordName => ['required', 'min:8',
'regex: // some long long regex'
],
// message
[
$passwordName.".regex" => "Your new password must be more than 8 characters long, should contain at-least 1 uppercase, 1 lowercase, 1 numeric and 1 special character.",
]
);
}
// Usr Id is by itself as it might be optional in registering.
public function validateNewUsrId(Request $request, $userIdName) {
$request->validate([
$userIdName => 'required|unique:users',
]);
}
然后我可以在我的控制器中像这样轻松地使用这个存储库。
$this->userRepository->validateNewEmail($request, "email");
$this->userRepository->validateNewPassword($request, "password");
$this->userRepository->validateNewUsrId($request, "usr_id");
原因是可能有多个控制器使用相同的规则,所以放在一个地方比较好
但是,我意识到这个 方法不起作用,因为它 return 只是第一个错误 。例如,当电子邮件和密码都错误时,只有电子邮件错误 returned 到前端。
实现我想要的最好方法是什么?我想把我所有的 validation/rules 放在一个地方以便重复使用。
我的第一个解决方案是:每个函数 returns 错误 MessageBag,然后将其连接在一起。我将使用 return $validator->errors();
到 return 可以在此处找到的 MessageBag https://laravel.com/docs/8.x/validation#retrieving-the-first-error-message-for-a-field
但是我有点不喜欢它,因为为了检查是否发生错误,我需要检查 MessageBag 是否为空,然后抛出一个看起来有点奇怪的错误。
我想到的另一种方法是 return 规则 ,这样我就可以在我的控制器中加入它们,然后一次性验证所有规则。这看起来更好,但我还必须合并 错误消息 ,如果有多个,这可能有点棘手(因为密钥不固定,请参见代码 $passwordName.".regex"
例如),因为我需要更新每条消息的密钥。
对我来说最好的方法是,如果我可以 return 每个函数的验证器,然后使用某种 Validate::ValidateAll 函数?这可能吗?
这通常是如何实现的?
现代 Laravel 应用程序通常使用 form request validation。使用这种方法,Laravel 会自动处理所有验证和 returns 错误消息。只需编写您的表单请求 class,然后在您的控制器方法中使用它代替 Request
:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rules\Password;
class MyFormRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'email' => ['required', 'email', 'unique:users'],
'password' => [
'required',
Password::min(8)->mixedCase()->numbers()->symbols()
],
'usrid' => ['required', 'unique:users'],
];
}
}
public method store(MyFormRequest $request)
{
// $request has been validated, no further checking needed
}
请注意,我使用的是 Laravel 的 built-in password validation rules 而不是依赖于“long long regex”。
刚开始我的第一个 PHP laravel 项目,我有这个
UserRepository.php
public function validateNewEmail(Request $request, $emailName) {
$request->validate([
$emailName => ['required', 'email', 'unique:users'],
]);
}
public function validateNewPassword(Request $request, $passwordName) {
$request->validate(
// rule
[
$passwordName => ['required', 'min:8',
'regex: // some long long regex'
],
// message
[
$passwordName.".regex" => "Your new password must be more than 8 characters long, should contain at-least 1 uppercase, 1 lowercase, 1 numeric and 1 special character.",
]
);
}
// Usr Id is by itself as it might be optional in registering.
public function validateNewUsrId(Request $request, $userIdName) {
$request->validate([
$userIdName => 'required|unique:users',
]);
}
然后我可以在我的控制器中像这样轻松地使用这个存储库。
$this->userRepository->validateNewEmail($request, "email");
$this->userRepository->validateNewPassword($request, "password");
$this->userRepository->validateNewUsrId($request, "usr_id");
原因是可能有多个控制器使用相同的规则,所以放在一个地方比较好
但是,我意识到这个 方法不起作用,因为它 return 只是第一个错误 。例如,当电子邮件和密码都错误时,只有电子邮件错误 returned 到前端。
实现我想要的最好方法是什么?我想把我所有的 validation/rules 放在一个地方以便重复使用。
我的第一个解决方案是:每个函数 returns 错误 MessageBag,然后将其连接在一起。我将使用 return $validator->errors();
到 return 可以在此处找到的 MessageBag https://laravel.com/docs/8.x/validation#retrieving-the-first-error-message-for-a-field
但是我有点不喜欢它,因为为了检查是否发生错误,我需要检查 MessageBag 是否为空,然后抛出一个看起来有点奇怪的错误。
我想到的另一种方法是 return 规则 ,这样我就可以在我的控制器中加入它们,然后一次性验证所有规则。这看起来更好,但我还必须合并 错误消息 ,如果有多个,这可能有点棘手(因为密钥不固定,请参见代码 $passwordName.".regex"
例如),因为我需要更新每条消息的密钥。
对我来说最好的方法是,如果我可以 return 每个函数的验证器,然后使用某种 Validate::ValidateAll 函数?这可能吗?
这通常是如何实现的?
现代 Laravel 应用程序通常使用 form request validation。使用这种方法,Laravel 会自动处理所有验证和 returns 错误消息。只需编写您的表单请求 class,然后在您的控制器方法中使用它代替 Request
:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rules\Password;
class MyFormRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'email' => ['required', 'email', 'unique:users'],
'password' => [
'required',
Password::min(8)->mixedCase()->numbers()->symbols()
],
'usrid' => ['required', 'unique:users'],
];
}
}
public method store(MyFormRequest $request)
{
// $request has been validated, no further checking needed
}
请注意,我使用的是 Laravel 的 built-in password validation rules 而不是依赖于“long long regex”。