表单验证的两种方法,以及验证失败时的数据保持
控制器验证$this->validate
基本使用
整个流程:如果没验证通过,那么框架会抛出一个异常,会被自动捕获,并重定向至用户的上一个页面,错误信息会存到session中,并自动将他们绑定于所有视图中,在视图中直接使用$errors数组判断即可,接下来我们来慢慢演示。
在控制器中,使用$this,指向的是当前的控制器。我们先来看HTML
<input type="text" name="Student[name]" placeholder="请输入学生姓名">
<input type="text" name="Student[age]" placeholder="请输入学生年龄">
<input type="radio" name="Student[sex]" value="10">男
<input type="radio" name="Student[sex]" value="30"> 女
然后我们在控制器app/Http/Controllers/StudentController.php中:
use Illuminate\Http\Request;
class StudentController extends Controller
{
public function create(Request $request)
{
// $this指的是当前控制器 是StudentController
$this->validate($request, [
'Student.name' => 'required|min: 2|max:20',
'Student.age' => 'required|integer',
'Student.sex' => 'required|integer',
]
}
}
注意$this->validate传入的第一个参数是$request。第二个参数传入每个input字段对应的验证规则,这里使用了数组input name="Student[name]", 所以要使用Student.name。如果是一个一维数组,那么:
$this->validate($request, [
'name' => 'required|min: 2|max:20',
'age' => 'required|integer',
'sex' => 'required|integer',
];
- required:代表必填
- min: 最少的字符串长度
- integer:必须为整型
- max: 最大字符串长度
- 多个规则用“|”进行分割
这样使用,在验证时,页面呈现出来的提示均是默认的英文提示,如果想要自定义提示,该怎么办呢?
自定义验证规则的提示
这个时候就需要提供第三个参数【类型是一个数组】
$this->validate($request, [
'Student.name' => 'required|min: 2|max:20',
'Student.age' => 'required|integer',
'Student.sex' => 'required|integer',
], [
// 第三个参数修改验证字段对应的提示信息
'required' => ':attribute 为必填项',
'min' => ':attribute 长度不符合要求',
'integer' => ':attribute 必须为整数'
])
其中:attribute是一个占位符,指向对应的属性。如果有如有有第四个参数就是属性对应的文字(下方进行展示)。这时候未通过提示结果为:
由此可见,:attribute对应的就是第二个参数中的Student.name。
自定义字段名
自定义字段名,就需要传入第四个参数【参数类型也为数组】
$this->validate($request, [
'Student.name' => 'required|min: 2|max:20',
'Student.age' => 'required|integer',
'Student.sex' => 'required|integer',
], [
// 第三个参数修改验证字段对应的提示信息
'required' => ':attribute 为必填项',
'min' => ':attribute 长度不符合要求',
'integer' => ':attribute 必须为整数'
], [
// 第四个参数修改字段Student.name对应的名称
'Student.name' => '姓名',
'Student.age' => '年龄',
'Student.sex' => '性别'
]);
这时候,提交验证不通过的时候,提示:
使用Validator验证类
Validator类验证,与控制器验证基本相同,除了第一个参数穿入$request->input()与控制器验证不同外, 之后传入的参数与控制器验证参数相同:
$validator = \Validator::make($request->input(),[
'Student.name' => 'required|min: 2|max:20',
'Student.age' => 'required|integer',
'Student.sex' => 'required|integer',
], [
// 第三个参数修改验证字段对应的提示信息
'required' => ':attribute 为必填项',
'min' => ':attribute 长度不符合要求',
'integer' => ':attribute 必须为整数'
], [
// 第四个参数修改字段Student.name对应的名称
'Student.name' => '姓名',
'Student.age' => '年龄',
'Student.sex' => '性别'
]);
注意:\Validator::make()前要加一个斜杠“\”
这个验证与控制器验证不同,不能自动重定向并绑定错误,需要手动判断验证是否成功:
// 如果验证有错误
if ($validator->fails()) {
// 手动重定向 返回上一页,它不会自动注册错误信息,需要手动注册
// 使用->withErrors($validator)并传入$validator类
return redirect()->back()->withErrors($validator);
}
- 如果要在视图模板中显示报错的信息,需要使用方法:->withErrors($validator),只要传入$validator验证类即可;
- 使用$validator->fails()判断是否通过验证。
将抛出的错误渲染到视图
我们先来看错误视图模板resources/views/common/validator.blade.php:
@if(count($errors))
<div class="alert alert-danger">
<ul>
{{--单独取出第一条--}}
<li>
{{ $errors->first() }}
</li>
{{-- $errors->all()即可调用他所有的错误 --}}
@foreach($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
- 通过控制器验证抛出的错误,是会自动存在session中,并可以在所有视图文件中通过$errors->all()遍历访问到;
- 通过Validator验证类抛出的错误,必须要在控制器中执行->withErrors(返回的验证类)绑定到临时的session数据中。
关于抛出的错误$errors
- 可以通过count($errors)来判断其中是否有数据,来决定是否需要渲染错误;
- $errors->all()即可调用他其中所有的错误;
- $errors->first() 可以取出错误中的第一条;
- $errors->first('Student.name') 可以指定要掉出谁的错误信息,比如:
<div class="col-sm-5">
<input type="text" name="Student[name]" placeholder="请输入学生姓名">
</div>
<div class="col-sm-5">
<p class="form-control-static text-danger">
{{--$errors->first指定要调谁的错误信息--}}
{{ $errors->first('Student.name') }}
</p>
</div>
当验证没通过,返回时保留之前的输入信息
以Validator验证类为例:
if ($validator->fails()) {
// 手动重定向 返回上一页,它不会自动注册错误信息,需要手动注册
// 使用->withErrors($validator)并传入$validator类
// ->withInput()当验证不成功的时候数据保持,原来输入框中内容依然存在
return redirect()->back()->withErrors($validator)->withInput();
}
使用->withInput()方法,然后在模板视图中:
<input type="text" id="name"
name="Student[name]"
value="{{ old ('Student')['name'] }}"
placeholder="请输入学生姓名"
>
但是这样写会出现报错:
Trying to access array offset on value of type null,数组找不到name属性。
这时我们就需要使用isset进行一下判断了:
<input type="text" name="Student[name]"
value="{{ isset(old ('Student')['name']) ? old ('Student')['name'] : '' }}"
placeholder="请输入学生姓名"
>
<input type="text" name="Student[age]"
value="{{ isset(old ('Student')['age']) ? old ('Student')['age'] : '' }}"
placeholder="请输入学生年龄"
这样写就会在验证失败的时候重定向回原来的页面,同时也保存之前输入的数据内容了。如下: