如何在 Laravel 项目中创建自定义表单请求验证
本教程介绍了如何在 Laravel(5.8 或 6+)项目中创建和使用自定义表单请求验证。
引言
本教程介绍了如何在 Laravel(5.8 或 6+)项目中创建和使用自定义表单请求验证。Laravel 中验证表单提交数据有几种方法。
控制器中的直接验证
标准方法是在控制器的开头直接使用 Validator
facade。 让我们看一个例子
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$validator = Validator::make($request--->all(), [
"title" => "required|min:5|max:200",
"body_content"=> "required|min:10",
"blog_tag_id" => "nullable",
],[
"title.required" => "Please write a title",
"title.min" => "The title has to have at least :min characters.",
"title.max" => "The title has to have no more than :max characters.",
"body_content.required" => "Please write some content",
"body_content.min" => "The content has to have at least :min characters",
]);
// ... next part of code after validation
}
如您在此示例中所见,我们在控制器的 action 中执行验证。这看起来还不错,直到您想在其他地方使用相同的代码:例如,在后端创建帖子,或者您想添加单元测试。在这种情况下,您将复制粘贴相同的代码片段,这不好,因为您必须维护所有这些代码,并且这种编程风格违反了 DRY 原则(不要重复自己)。
使用自定义验证器
那么... 实现这种验证的更好方法是什么? Laravel 允许我们创建自己的 Request
类,而不是使用标准的 \Illuminate\Http\Request 并将其作为函数参数使用。 让我们看看如何做到这一点。
首先要做的是创建此类。 运行以下命令
$ php artisan make:request App\Http\Requests\MyOwnRequest
此命令将在 App\Http\Requests\ 目录中创建 MyOwnRequest
请求类。 默认情况下,它将如下所示
namespace App\Http\Requests\Auth;
use Illuminate\Foundation\Http\FormRequest;
class MyOwnRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
* @return bool
*/
public function authorize()
{
return false;
}
/**
* Get the validation rules that apply to the request.
* @return array
*/
public function rules()
{
return [
//
];
}
}
现在您可以将验证规则移动到那里,并将 store()
方法中的 Request 参数替换为 MyOwnRequest
。
您的控制器 store()
方法将如下所示
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\MyOwnRequest $request
* @return \Illuminate\Http\Response
*/
public function store(MyOwnRequest $request)
{
// ... next part of code after validation
}
MyOwnRequest
类将如下所示
(请记住将 authorize()
方法的返回值设置为 TRUE
!)
namespace App\Http\Requests\Auth;
use Illuminate\Foundation\Http\FormRequest;
class MyOwnRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
"title" => "required|min:5|max:200",
"body_content"=> "required|min:10",
"blog_tag_id" => "nullable",
];
}
}
看起来好多了,对吧?
请求类的自定义
自定义消息
现在,如果您想指定自定义验证消息怎么办? 可以使用验证器类的 messages()
方法轻松实现。 您只需定义一个数组,其中键是字段名称,值是您想要显示的自定义消息。
namespace App\Http\Requests\Auth;
use Illuminate\Foundation\Http\FormRequest;
class MyOwnRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
"title" => "required|min:5|max:200",
"body_content"=> "required|min:10",
"blog_tag_id" => "nullable",
];
}
/**
* Custom message for validation
*
* @return array
*/
public function messages()
{
return [
"title.required" => "Please write a title",
"title.min" => "The title has to have at least :min characters.",
"title.max" => "The title has to have no more than :max characters.",
"body_content.required" => "Please write some content",
"body_content.min" => "The content has to have at least :min characters",
];
}
}
字段集的验证
好的,现在看起来更好。 但是,如果您需要验证一组字段怎么办,例如:几个复选框或几个文件字段? 在这种情况下,您可以使用星号 * 来准备验证规则。 请查看下面的示例,了解我们如何定义字段集的验证规则。 我希望它足够清晰易懂。
public function rules(): array
{
return [
"files.*" => "required|image|mimes:jpg,jpeg,png",
"attrs.*.from" => "nullable|numeric",
"attrs.*.to" => "nullable|numeric",
];
}
属性的特殊命名
如您所知,Laravel 会自动创建验证消息,因此有时您需要为字段提供特殊名称。 您可以使用以下语言行来交换属性占位符,例如将“email”替换为“电子邮件地址”,或数组中的索引,以使消息更易于阅读。 这只是为了帮助我们使消息更简洁。
public function attributes(): array
{
return [
"receivers" => "Nice name",
"subject" => "Like name",
"body" => "Another Name",
"notify.blog.*" => "Blog Notification value",
];
}
添加您自己的验证
现在,如果您想执行自己的验证,可以使用 withValidator()
方法。 当您需要在主验证通过(或未通过)后执行其他或非常复杂的验证时,它很有用。 在下面的示例中,我们检查电子邮件是否在预先批准的电子邮件列表中。 请注意,您可以使用一些方法
$validator->after()
$validator->fails()
等等。
/**
* @param \Illuminate\Validation\Validator $validator
* @return void
*/
public function withValidator(Validator $validator)
{
$email = $validator->getData()['email'] ?? '';
$validator->after(
function ($validator) use ($email) {
if (is_null(\DB::table('pre_approved')->where('email',$email)->first())) {
$validator->errors()->add(
'email',
'This email does not exist on our pre-approved email list'
);
}
}
);
}
不要忘记授权
如前所述,表单请求类还包含一个 authorize
方法。 您可以检查经过身份验证的用户是否实际上有权更改给定的资源。 让我们看一个例子,当用户实际拥有博客评论并尝试更新它时
/**
* Check if the user is authorized to make this request.
* @return bool
*/
public function authorize()
{
$comment = Comment::find($this->route('comment'));
return $comment && $this->user()->can('update', $comment);
}
自定义重定向
最后,如果您想重新定义验证失败时的路由,可以通过重新定义 $redirectRoute
属性来完成。
// The named route to redirect to if validation fails.
protected $redirectRoute = 'home';
历史
- 2021 年 1 月 15 日:初始版本