驗證器
By:Mirror王宇陽
驗證器定義
驗證器的使用,必須定義它;系統提供了一條命令直接生產一個驗證器類:
php think make:validate User
自動再應用目錄下生成一個
validate
文件夾,並生成User.php
類
namespace app\validate;
use think\Validate;
class User extends Validate
{
/**
* 定義驗證規則
* 格式:'字段名' => ['規則1','規則2'...]
* '字段名' => '規則1|規則2...'
*
* @var array
*/
protected $rule = [
'name' => 'require|max:20',
'price' => 'number|between:1,100',
'email' => 'email'
];
/**
* 定義錯誤信息
* 格式:'字段名.規則名' => '錯誤信息'
*
* @var array
*/
protected $message = [
'name.require' => '姓名不得為空',
'name.max' => '姓名不得大於20位',
'price.number' => '價格必須是數字',
'price.between' => '價格位於1~100之間',
'email' => '郵箱格式錯誤'
];
}
自動生成的兩個屬性:
$rule
:定義規則
$message
:定義錯誤信息 ,如果不定義錯誤信息提示默認的錯誤信息
驗證器定義之后,進行調用測試,創建一個Verify.php
控制器:
namespace app\controller;
use app\validate\User;
use think\exception\ValidateException;
class Verify
{
public function index()
{
try {
validate(User::class)->check([
'name' => '蠟筆小新',
'price' => 90,
'email' => 'xiaoxin@qq.com'
]);
} catch (ValidateException $err){
dump($err->getError());
}
}
}
當驗證規則出現一個錯誤后就會停止之后字段的判斷
批量驗證
class Verify
{
public function index()
{
try {
$result = validate(User::class)
->batch(true)->check([
'name' => '蠟筆小新',
'price' => 90,
'email' => 'xiaoxin@qq.com'
]);
if(true !== $result){
dump($result);
}
} catch (ValidateException $err){
dump($err->getError());
}
}
}
自定義規則
系統內置提供了部分常用的規則;同時也允許開發者自定義規則:
protected function checkName($value,$rule)
{
return $rule != $value ? true : '存在非法字符';
}
自定義規則支持傳入五個參數:
- 驗證數據
- 驗證規則
- 全部數據(數組)
- 字段名
- 字段描述
驗證規則
規則定義
protected $rule = [
'name' => 'require|max:20',
'price' => 'number|between:1,100',
'email' => 'email'
];
不僅僅支持字符串模式,也支持數組模式
protected $rule = [
'name' => [
'require',
'max' => 10
],
'price' => [
'number',
'between' => '1,100'
],
'email' => ['email']
];
數組模式是在規則復雜的時候使用
獨立驗證:
上述的各種驗證規則都需要調用
validate
目錄下的驗證器文件,而Think支持在控制器文件下獨立驗證;這種不依賴驗證器文件的調用方式是一種獨立、唯一的調用方式
namespace app\controller;
use think\facade\Validate;
class Verify
{
public function index()
{
$validate = Validate::rule([
'name' => 'require|max:20',
'price' => 'number|between:1,100',
'email' => 'email'
]);
$result = $validate->chech([
'name' => '蠟筆小新',
'price' => 90,
'email' => 'xiaoxin@qq.com'
]);
if (!$result){
dump($validate->getError());
}
}
}
獨立驗證支持對象化的定義方式,但不支持屬性方法的定義:
namespace app\controller; use think\facade\Validate; use think\facade\ValidateRule as Rule; class Verify { public function index() { $validate = Validate::rule([ 'name' => 'Rule::isRequire()->max(20)', 'price' => 'Rule::isNumber()->between([1,100])', 'email' => 'Rule::isEmail()' ]); $result = $validate->chech([ 'name' => '蠟筆小新', 'price' => 90, 'email' => 'xiaoxin@qq.com' ]); if (!$result){ dump($validate->getError()); } } }
獨立驗證支持閉包自定義方法:(不支持字段多規則)
$validate = Validate::rule([
'name'=> function($value){
return $value != '' ? true : '姓名不得為空';
},
'price'=> function($value){
return $value > 0 ? true:'不得低於零';
}
]);
錯誤信息
單獨定義提示信息
在驗證器類中定義message
屬性:
protected $message = [
'name.require' => '姓名不得為空',
'name.max' => '姓名不得大於20位',
'price.number' => '價格必須是數字',
'price.between' => '價格位於1~100之間',
'email' => '郵箱格式錯誤'
];
錯誤信息支持數組定義,並通過JSON方式交給前端
protected $message = [
'name.require' => ['code' => 1001, 'msg' => '名稱必須'],
'name.max' => ['code' => 1002, 'msg' => '名稱最多不能超過25個字符'],
'age.number' => ['code' => 1003, 'msg' => '年齡必須是數字'],
'age.between' => ['code' => 1004, 'msg' => '年齡必須在1~120之間'],
'email' => ['code' => 1005, 'msg' =>'郵箱格式錯誤'],
];
獨立驗證定義錯誤提示
ValidateRule::isEmail(null,'格式不正確')
參數一:驗證規則
參數二:自定義錯誤提示
也可以獨立使用
message()
方法:Validate->[……]->message([……])
驗證場景
驗證場景設置:即特定的場景寫是否進行驗證,獨立驗證不存在場景驗證;
新增數據需要驗證郵箱信息,而修改數據不需要驗證郵箱信息
namespace app\validate;
use think\Validate;
class User extends Validate
{
protected $rule = [
'name' => 'require|max:20',
'price' => 'number|between:1,100',
'email' => 'email'
];
protected $message = [
'name.require' => '姓名不得為空',
'name.max' => '姓名不得大於20位',
'price.number' => '價格必須是數字',
'price.between' => '價格位於1~100之間',
'email' => '郵箱格式錯誤'
];
protected $scene = [
// 新增數據驗證三個字段
'insert' => ['name','price','email'],
// 更新數據驗證兩個字段
'edit' => ['name','price']
];
}
try {
validate(User::class)->scene('edit')->check([
'name' => '蠟筆小新',
'price' => 90,
'email' => 'xiaoxinqq.com'
]);
} catch (ValidateException $err){
dump($err->getError());
}
在控制端設置
scene()
就成功的限制只驗證name
和price
兩個字段
scene
支持為單個場景單獨定義方法,方法的命名規范是scene+場景名
,采用駝峰寫法;
同時在驗證類中支持公共方法對場景中的細節進行定義:
public function sceneEdit()
{
return $this->only(['name','price'])
->append('name','min:5')
->remove('price','between')
->append('price','require|max:20');
}
append
追加
remove
移除(不要對一個字段多次操作,會導致覆蓋;可以同時操作)
only
約束字段
路由驗證
路由驗證:在路由參數調用驗證類進行驗證
protected $rule = [
'id' => 'number|between:1,10'
];
protected $message = [
'id.between' => 'id介於1~10之間',
'id.number' => 'id必須是數字'
];
protected $scene = [
'route' => ['id'];
];
Route::rule('vr/:id','Verify/route')->validate(User::class,'route');//只執行route場景
也支持使用獨立的驗證方式,這里不贅述……
內置規則
靜態方法支持兩種形式:::number()
、isNumber()
方法驗證
格式驗證類
屬性/方法 | 描述 |
---|---|
require /::isRequire |
不得為空 |
number /::isNumber |
驗證字段是否為純數字 |
integer /::isInteger |
驗證字段是否為整數 |
float /::isFloat |
驗證字段是否為浮點數 |
boolean /::isBoolean |
驗證字段是否為布爾值 |
email /::isEmail |
驗證字段是否為郵箱格式 |
array /isArray |
驗證字段是否為數組 |
accepted /isAccepted |
驗證字段是否為yes/on |
date /isDate |
驗證字段是否為有效日期 |
alpha /isAlpha |
驗證字段是否為純字母 |
alphaNum /isAlphaNum |
驗證字段是否為純字母數字組合 |
alphaDash /isAlphaDash |
驗證字段是否為字母數字下划線破折號組好 |
chs /isChs |
驗證字段是否為漢字 |
chsAlpha /isChsAlpha |
驗證字段是否為漢字字母 |
chsAlphaNum /isChsAlphaNum |
驗證字段是否為漢字字母和數字 |
chsDash /isChsDash |
驗證字段是否為字母數字下划線破折號組好和漢字 |
cntrl /isCntrl |
驗證字段是否為控制字符(空格、縮進) |
graph /isGraph |
驗證字段是否為可打印字符(不包括空格) |
print /isPrint |
驗證字段是否為可打印字符(包括空格) |
lower /isLower |
驗證字段是否為小寫 |
upper /isUpper |
驗證字段是否為大寫 |
space /isSpace |
驗證字段是否為空白字符 |
xdigit /isXdigit |
驗證字段是否為十六進制 |
activeUrl /isActiveUrl |
驗證字段是否為有效域名 |
url /isUrl |
驗證字段是否為有效URL地址 |
ip /isIp |
驗證字段是否為有效IP地址 |
deteFormat:format |
驗證字段的日期時間格式 |
mobile |
驗證字段是否為有效手機號 |
idCard |
驗證身份證格式 |
macAddr |
驗證MAC地址格式 |
zip |
驗證有效郵政編碼 |
長度和區間驗證類
屬性 | 描述 |
---|---|
in |
驗證字段是否在某個范圍 |
notIn |
驗證字段是否不再某個范圍 |
between |
驗證字段是否在某個區間 |
notBetween |
驗證字段是否不在某個區間 |
length |
驗證長度是否在某個范圍或指定長度 |
max /min |
驗證最大/最小長度(大小) |
after |
驗證是否在某個日期之后 |
before |
驗證是否在某個日期之前 |
expire |
驗證當前值是否在某個時間區間內 |
allowip |
驗證當前值是否在某個IP段范圍內 |
denyIp |
驗證當前值IP是否為禁止訪問的IP |
字段比較類
屬性 | 描述 |
---|---|
confirm:field |
驗證字段的值是否和其它的值一致 |
different:field |
驗證字段的值是否和其它的值不一致 |
eq /same /= |
驗證是否等於某個值 |
egt / >= |
驗證是否大於等於某個值 |
gt /> |
驗證是否大於某個值 |
elt /<= |
驗證是否小於等於某個值 |
lt /< |
驗證是否小於某個值 |
上傳驗證類
屬性 | 描述 |
---|---|
file |
驗證上傳的是否是一個文件 |
image |
驗證是否是一個圖像文件(可以約束width height type) |
fileExt |
驗證文件后綴(可以允許后綴名單) |
fileMime |
驗證文件類型(可以允許文件類型) |
fileSize |
驗證文件大小(可以允許的字節大小) |
其他驗證類
filter驗證:
支持使用filter_var
進行驗證,例如:
'ip'=>'filter:validate_ip'
正則驗證:regex
支持使用正則表達式進行驗證:
'data' => '\d{6}';
'data' => 'regex:\d{6}';
若表達式中包含或邏輯,需要使用數組方式定義
'data' => ['regex'=>'/^(yes|on|1)$/i']
同時也可以預定義
namespace app\index\validate;
use think\Validate;
class User extends Validate
{
protected $regex = [ 'zip' => '\d{6}'];
protected $rule = [
'name' => 'require|max:25',
'email' => 'email',
];
}
然后就可以使用
'zip' => 'regex:zip',
表單令牌驗證:token
參考連接:https://www.kancloud.cn/manual/thinkphp6_0/1037632
驗證請求字段唯一:unique
可以驗證當前請求的字段值是否為唯一的
unique:[table],[field],[except],[pk]
table:指定數據表
field:其他字段
except:排除某個主鍵值
pk:指定某個主鍵值排除
// 表示驗證name字段的值是否在user表(不包含前綴)中唯一
'name' => 'unique:user',
// 驗證其他字段
'name' => 'unique:user,account',
// 排除某個主鍵值
'name' => 'unique:user,account,10',
// 指定某個主鍵值排除
'name' => 'unique:user,account,10,user_id',
require:
屬性 | 描述 |
---|---|
requireIf:field,value |
驗證某個字段的值等於某個值的時候必須 |
requireWith:field |
驗證某個字段有值的時候必須 |
requireWithout:field |
驗證某個字段沒有值的時候必須 |
requireCallback:callable |
驗證當某個callable為真時候字段必須 |
靜態調用驗證
靜態調用:使用facade模式進行調用驗證,適合驗證單個數據
引入facade中的Validate
時候可能會發生沖突,需要留意;
dump(Validate::isEmail('xiaoxin@qq.com'));
靜態調用支持多規則驗證:checkRule()
Validate::checkRule(10, 'number|between:1,10');
注解驗證
參考官方:https://www.kancloud.cn/manual/thinkphp6_0/1375936
安裝額外的擴展:
composer require topthink/think-annotation