验证
有点像tp的Model自动验证,但是不是绑定在Model中的,而是有一个专门的类的。
控制器中调用形式
直接看代码吧:
public function store(Request $request){
$this->validate($request,[
'title'=>'required',
'body'=>'required'
]);
//这里下面可以开始直接写验证通过的业务逻辑
}
如果验证不通过的话,那么会直接终止程序的运行并返回到上一个页面,如果你在页面中使用了{{old('filedName')}}
的话,那么旧的输入就会保留在其中。注意!不是停止接下来的验证,还会进行接下来的验证,会把所有不符合的验证自动生成一个提示信息,如何得到该错误信息暂且不说,这里的停止指的是$this->validate();
之后的代码不会运行!
验证规则
上面只写了一个例子:required
,这里把所有的规则列出来,给自己一个方便查看的地方:
accepted
结果必须是yes on 1 true
,这些中的一个值才可以。
url
active_url
验证结果必须是函数dns_get_record
返回值中的一个值才行
after:date
date
指的是一个具体的值,传递过来的待验证字段会首先经过PHP的strtotime
函数转换成时间戳,与date
进行比较,只有大于date
时才可以通过验证。
after_or_equal:date
跟after:date
很像,只不过after:date
是>
,而这个是>=
。
before:date
before_or_equal:date
就是跟上面的两个对应的。
between:min,max
接受数值、字符串和文件。
max:value
min:value
boolean
接受true,false,1,0,"1","0"
。
alpha
必须是字母
alpha_dash
可以是字母、数字、破折号和下划线
alpha_num
必须是字母、数字
nullable
array
必须是PHP的array数组
confirmed
这里直接举一个例子比较好理解:
<form action="?" method="post">
<input name='password' type='password' />
<input name='password_confirmed' type='password' />
</form>
这里要求用户输入一次密码之后再输入一次确定,这是就可以在后台直接设置:
$this->validate([
'password'=>'confirmed'
]);
这时Laravel会自动去验证name='password_confirm'
的输入是否和password
的输入一样。而不需要我们人为手工去编写比较函数!
注意!name参数的命名方式,待验证字段名字:validateFieldName,相同验证:validateFieldName_confirmed
date
能被strtotime
函数接受,并转换成时间戳的字符串。
date_format:format
可以被date
或者date_format
能接受的格式,并且和format
格式相同。
different:field
这个不知道是什么意思??
digits:value
长度为value
的数字。
digits_between:min,max
dimensions
这个是专门针对图片的,有效设置有:
- min_width
- max_width
- min_height
- max_height
- width
- height
- ratio
ratio
表示的是宽度/高度。
这里举个例子:
'avatar' => 'dimensions:min_width=100,min_height=200',
'avatar2' => 'dimension:ratio=3/2'
distinct
当处理数组时,不允许有重复值!
exists:table,column
file
该字段必须是文件
image
必须是图片
mimetypes:mimeType
必须是MiME的文件类型之一。
还有一个类似的,但是我不知道两者有什么区别:mimes:
in:value1,value2,value3……
待验证字段的值必须是value1 value2 value3 ......
等值中的一个
not_in:value1,value2,value3……
in_array:anotherInputName
这里假设一个表单如下:
<form action="?" method='post'>
<input name='inputName[]' value='inputValue1' />
<input name='inputName[]' value='inputValue2' />
<input name='inputName[]' value='inputValue3' />
<input name='validateFieldName' value='inputValue1' />
</form>
然后设置该验证:
'validateFieldName'=>'in_array:inputName'
只有validateFidleName
的值,在inputName
中存在时,才会通过验证。
integer
整型。
numeric
支持小数。
ip
ipv4
ipv6
json
regex:正则
正则匹配
required
值为null 空字符串 空数组
时,都不符合该验证。
required_if:anotherFieldName,value
只有在anotherFieldName
字段的值为value
时,才对待验证字段启动required
验证。
required_unless:anotherFieldName,value
只有当anotherFieldName
字段的值为value
时,才关闭对待验证字段的required
验证。
required_with:anotherFieldName1,anotherFieldName2……
只有anotherFieldName1
或者anotherFieldName2
字段存在时,才进行required
验证。
required_with_all:anotherFieldName1,anotherFieldName2…..
只有anotherFieldName1
和anotherFieldName2
都存在时,才开启required
验证。
required_without:anotherFieldName1,anotherFieldName2…..
只有当anotherFieldName1,anotherFieldName2.....
其中之一不存在时,才开启验证。
required_without_all:anotherFieldName1,anotherFieldName2…..
只有当anotherFieldName1,anotherFieldName2.....
都不存在时,才开启验证
same:field
待验证字段必须和field
字段匹配。
size:value
这里的value
是针对不同的类型有不同的含义:
- 字符串:字符数量
- 数值:必须相等
- 文件:文件字节数
string
timezone
时区???
unique:table,column,expect,PrimaryKey
验证字段在该table
下的column
字段的值中必须是唯一的,除了(expect
)中,主键值为PrimaryKey
的记录之外。后两个参数可选。
exists:table,column,tableField,condition
待验证字段的值必须存在于指定table
表的column
中,还可以加上类似where
的判断,比如后面的两个参数,具体调用格式就像下面:
select column from table where tableField condition;
这里的condition
可直接是一个具体的值,比如1,也可以是!1
,或者是NULL
,NOT_NULL
。
错误信息
当验证失败后会有验证信息,该验证信息被自动保存在$error
中,直接在视图中使用该变量就能将不符合上面验证的全部信息进行一个输出:
@if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
这里只是演示如何在模板中输出全部的错误信息。但是这里有一个问题,Laravel默认是英语环境,所以提示信息都是英文的,这不符合国情,所以为了使错误显示信息更加人性化,我们在这里更换语言环境。
更换Laravel语言包
首先先去github上下载大神写的中文语言包:各种语言包,在其中选择zh-CN
,下载好后把其放到:resource/lang
中,并在config/app.php
中把'locale'=>'en'
替换成'locale'=>'zh-CN'
。
has()
判断一个待验证字段是否有错误信息
if($error->has('inputFieldName')){
//
}
中间件与验证
在web
中间件中设置有两个输入转换中间件:TrimStrings
和ConvertEmptyStringToNull
,这两个中间件的作用就是将输入的字符串首尾的空格去掉,将空的输入转换成值为null
。
这样表格中的一些可选项就要设置成nullable
。
Ajax请求与验证
上面显示错误信息时是使用$error
直接在模板中进行输出,但是当使用Ajax进行表单的提交时,并且验证失败时,Laravel会自动创建Ajax返回,该返回信息包含一个错误信息的JSON响应以及422
的HTTP状态码。
创建专门的验证文件
上面我们是直接在控制器中设置验证信息的,也可以像tp一样,将验证和控制器代码分割开来。
命令行创建验证文件
php artisan make:request RequestFileName
这个命令会在app\Http\Requests
下创建RequestFileName.php
文件,该文件的内容如下:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class RequestFileName extends FormRequest
{
/**
* Determine if the user is authorized to make this request.确定是否授权用户发出此请求。
* 简单来说就是只有这里返回true,验证才会开始,否则直接返回验证不通过
* @return bool
*/
public function authorize()
{
return false;
}
/**
* 像在控制器的validate中设置验证规则一样
* @return array
*/
public function rules()
{
return [
//
];
}
}
要调用上面的验证,只需要在需要该验证文件的地方将该验证类作为参数传递进去。
public function store(RequestFileName $request){
// 到达这里的请求$request已经经过RequestFileName类的验证了
}
自定义错误信息
在控制器中重写message
方法,比如:
public function message(){
return [
'inputName1'=>'错误信息',
'inputName2'=>'错误信息2,这样更加具有针对性'
];
}
手动创建验证器
public function store(Request $request)
{
// 这里使用Validator::make()来创建新的验证器
$validator = Validator::make($request->all(), [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
if ($validator->fails()) {
return redirect('post/create')
->withErrors($validator)
->withInput();
}
}
重定向
public function store(Request $request)
{
// 这里使用Validator::make()来创建新的验证器
$validator = Validator::make($request->all(), [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
])->validate();
//这里加上validate()会使新建的验证器具有自动重定向功能
if ($validator->fails()) {
return redirect('post/create')
->withErrors($validator)
->withInput();
}
}
重定向时传递错误信息
return redirect('RouteName')->withErrors($validator,'ErrorMessageName');
接着在别的地方只要这样就可以调用上一个页面传递过来的错误了:
{{$error->ErrorMessageName->all()}}
验证后的回调函数
$validate->after(function($validator){
//这里执行回调函数
});
自定义错误信息
$errorMessage=[
'inputName'=>'错误信息'
];
$validator=Validator::make($inputDate,$rule,$errorMessage);
或者你可以结合专门的匹配条件来设置错误提示信息,这样的设置也可以利用到上面的自定义错误信息中:
$errorMessage=[
'inputName.required'=>'只有该inputName的required不满足时才会显示该错误信息'
];