正文 【Laravel基础】19. 表单与验证 拾年之璐 V管理员 /2021年 /644 阅读 0219 ## 19. 表单与验证 [TOC] ### 19.1 表单快速验证 > 快速验证方法,适合小规模的单独验证。 1、首先,创建两个路由,一个是表单的页面,另一个是表单提交后的处理页面: ````php //表单页 Route::get('/task/form','TaskController@form'); //接收页 Route::post('/task/receive','TaskController@receive'); ```` 2、然后,创建一个页面 `form.blade.php`,来作为表单提交的演示页面: ```html @csrf 用户名: 密码: 提交 ``` > {{old('username')}}:表示回调后,自动填充已经填写的信息。 3、接下来,在 `TaskController.php` 控制类中,写入方法 `receive()` ,通过 `Request` 对象来实现字段验证,如下: ```php //Request 是 Illuminate\Http\Request 下的 public function receive(Request $request) { //验证请求方式 //左边为验证字段,右边为验证规则,每个规则竖线隔开 //比如required 不得为空,min 不等小于,max 不得大于 $request->validate([ 'username' => 'required|min:2|max:10', 'password' => 'required|min:6', ]); //只有通过才能执行下面的语句,否则返回表单页 return '恭喜验证通过!'; } ``` 4、如果验证没有被通过,会自动重定向到提交页,并将错误信息存储到session 中。 其内部操作是通过中间件实现的,其中间件的位置:`Illuminate\View\Middleware\ShareErrorsFromSession`,文件路径:`vendor\laravel\framework\src\Illuminate\View\Middleware\ShareErrorsFromSession.php` 打开这个文件,可以看到,有一个方法返回的是一个名为 `errors` 的参数。在前端页面,可以使用该参数进行各种操作。 如遍历打印错误信息: ```php+HTML {{--如果有验证失败的错误信息, any()=1 --}} @if ($errors->any()) @foreach ($errors->all() as $error) {{ $error }} @endforeach @endif ``` 也可以单独设置错误信息,使用 `@error` 命令: ```php @error('username') {{ $message }} : 用户名非法! @enderror @error('password') {{ $message }} : 密码非法! @enderror ``` 5、关于规则,还有其它写法,具体如下: ```php //数组方式验证 $request->validate([ 'username' => ['required', 'min:2', 'max:10'], 'password' => ['required', 'min:6'] ]); ``` > 这里注意,中间还是以冒号间隔。 ### 19.2 验证类的使用 > 所谓验证类,是将验证规则写在一个验证类中,然后进行调用。 1、创建验证类的方法:使用命令创建验证类 ```php php artisan make:request Form ``` > 最后的Form是验证类的类名,可以根据实际情况修改。 然后即可在 `app/http` 目录下,新建一个名为 `Requests` 的文件,验证类 `Form.php` 就在该文件下。 2、验证类 `Http\Request\Form.php` 创建好之后,会提供两个固定方法; ```php public function authorize() { //默认false,为关闭授权,关闭状态会403 //比如判断这个用户是否有操作权限 return true; } public function rules() { return [ //规则 ]; } ``` 然后在上面的 `rules()` 方法中,写入验证规则: ```php public function rules() { return [ //规则如下 'username' => 'required|min:2|max:10', 'password' => 'required|min:6', ]; } ``` 3、在控制器端,直接使用验证类进行验证即可,其它和快速验证一样; ```php public function receive(Form $request) { //通过验证类验证 $request->validated(); //只有通过才能执行下面的语句,否则返回表单页 return '恭喜验证通过!'; } ``` 这里注意,控制器的方法的参数,是`Form` 中的$request。 > 以下几种方法是已经实现的,可以重构修改。 4、在请求验证之前,可以修改提交的请求数据,在`验证类创建prepareForValidation()`实现: ```php protected function prepareForValidation() { $this->merge([ 'username' => 'Mr.Lee' ]); } ``` > 这时,不管前端提交的username是什么,都没用。 5、默认错误提示是英文的,如果想设置成中文提示,可在`验证类创建message()`实现; ```php //验证器类方法 public function messages() { return [ 'username.required' => '用户名不得为空', 'username.min' => '用户名不得小于2 位', 'username.max' => '用户名不得大于10 位', 'password.required' => '密码不得为空', 'password.min' => '密码不得小于6 位', ]; } ``` 6、也可以自定义属性名,而其它采用默认提示;在`验证类创建attributes()`修改实现: ```php public function attributes() { return [ 'username' => '用户名', ]; } ``` > PS:提示语言包在:resources\lang\en\validation.php 7、每次都要自己修改验证类的提示,实属麻烦,可以直接下载官网的中文语言包。 > 官网资源地址:[https://github.com/Laravel-Lang/lang](https://github.com/Laravel-Lang/lang) > > 下载后,将`zh_CN` 这个文件,放在 `resources\lang` 目录下, > > 然后修改 `config/app.php` 中的 `'locale' => 'zh_CN'` 即可。 > > 然后,其他的提示,可根据实际情况调整修改。 ### 19.3 手动验证的实现 > 手动验证,和第一节快速验证是一样的,都是在控制器验证;只不过,快速验证是全自动化的,无法局部控制更多的细节。 > > 而手动验证,可以实现更多的局部细节。 1、首先在控制类的具体方法中,创建手动验证,方法如下: ```php //手动创建验证器 $validator = Validator::make($request->post(), [ 'username' => 'required|min:2|max:10', 'password' => 'required|min:6', ]); ``` > 这里注意: > > Validator是Illuminate\Support\Facades\Validator; > > make方法传入的两个参数,第一个是Request请求的数据,第二个是具体的验证规则数组。 2、然后在控制类中,使用 `$validator` 的 `fails()` 方法,可以对验证的成败进行判断,如下: ```php //如果没有通过的话 if ($validator->fails()) { //跳转后,并将错误保存,还可以返回上一次填的信息 return redirect('/task/form')->withErrors($validator)->withInput(); // redirect:跳转; // withErrors:带上错误信息; // withInput:带上输入的表单旧数据。 } ``` 3、如果同一个页面有多个表单,可以设置 $errors 的多个错误包,有两种方法定义: 一种是,在创建手动验证的时候,定义: ```php $validator = Validator::make($request->post(), [ 'username' => 'required|min:2|max:10', 'password' => 'required|min:6', ])->validateWithBag('a'); //设置快速验证和手动验证,针对a表单。 ``` 另一种是,页面跳转的时候,定义: ```php if ($validator->fails()) { //跳转后,并将错误保存,还可以返回上一次填的信息 return redirect('/task/form')->withErrors($validator, 'a')->withInput(); // redirect:跳转; // withErrors:带上错误信息;其中的参数表示此验证是针对a表单的; // withInput:带上输入的表单旧数据。 } ``` 然后,在前端,使用如下方法显示错误信息: ```php+HTML @if ($errors->a->any()) @foreach ($errors->a->all() as $error) {{ $error }} @endforeach @endif ``` 4、我们也可以在验证完毕之前,通过附加回调添加更多的自定义错误信息; 在控制类中,接着定义之后: ```php //验证钩子 $validator->after(function ($validator) { //判断你要判断的内容 $validator->errors()->add('info', '隐藏字段info 的值不存在'); }); ``` 5、关于 `$errors` 对象,除了 `any()` 判断, `all()` 获取全部,还有一些别的方法; ```php {{--获取指定字段第一条信息--}} {{$errors->first('username')}} {{--判断指定字段是否有错误信息--}} {{$errors->has('username')}} ``` ### 19.4 验证规则大全 > 验证规则,提供了大量实用封装好的规则,我们只需要进行调用即可; > > 完整的验证规则,详见:[https://learnku.com/docs/laravel/7.x/validation/7467#available-validation-rules](https://learnku.com/docs/laravel/7.x/validation/7467#available-validation-rules) > >  前面,我们使用了 `required`、`min` 和 `max` 这三种比较简单的;下面,挑出比较典型常用的。 1、`alpha_dash`:字段必须由字母、数字破折号(-)和下划线(_)构成; ```php 'username' => 'required|alpha_dash', ``` 2、`between`:字段长度必须在指定的区间之间 ```php 'username' => 'required|between:2,6', ``` 3、`size`:字段长度固定在某个值 ```php 'username' => 'required|size:6', ``` 4、`email`:字段必须符合email 格式; ```php 'username' => 'required|email', ``` 5、`unique:users`:字段值是唯一的,通过指定数据表字段检查; ```php 'username' => 'required|unique:users', ``` 6、`confiremed`:这个基本用于密码和密码确认,固定了字段名称; ```php 'password' => 'required|min:6|confirmed', ``` 7、`different:password`:字段和另一个字段不可以相同的验证; ```php 'username' => 'required|different:password',//即username不能和password相同。 ``` 8、`ip` / `json`:字段是否是ip 地址/字段是否是json 数据; ```php 'username' => 'required|ip', 'username' => 'required|json', ``` > 还有一些其他格式的用法,如下: 9、验证方法还提供了 `Rule 类` 提供更加流程的验证构造,比如 `in` 、`not_in` ; ```php ///username只能从指定的范围取值: 'username' => 'required|in:tom,jack,lusy', //推荐下面这种 'username' => [ 'required', Rule::in(['tom', 'jack', 'lusy']) ], //如果只验证一个规则,不需要数组,如果规则名有下划线,首字母大写 'username' => Rule::notIn(['tom', 'jack', 'lusy']), ``` 10、`Rule 类 `还可以结合 `where `来限制验证范围等操作; ```php //验证是否重复 'username' => Rule::unique('users'), 'username' => Rule::unique('users')->where(function ($query) { $query->where('id', 20); }), ``` 以上。 本文采用创作共用版权 CC BY-NC-SA 3.0 CN 许可协议,转载或复制请注明出处! -- 展开阅读全文 --