溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

ThinkPHP自動(dòng)驗(yàn)證分析

發(fā)布時(shí)間:2020-08-06 15:29:45 來源:網(wǎng)絡(luò) 閱讀:1002 作者:小海哥2010 欄目:web開發(fā)

今天一起來學(xué)習(xí)下TP的自動(dòng)驗(yàn)證具體是怎么實(shí)現(xiàn)的,首先驗(yàn)證規(guī)則的定義格式如下:

// 驗(yàn)證因子定義格式

array(field,rule,message,condition,type,when,params)

field:驗(yàn)證字段的名稱

rule:驗(yàn)證表達(dá)式

message:錯(cuò)誤信息

condition:驗(yàn)證條件,0存在就驗(yàn)證 1 必須驗(yàn)證 2值不為空時(shí)驗(yàn)證

type:驗(yàn)證方式

when:什么時(shí)候驗(yàn)證 1插入時(shí) 2 更新時(shí) 3兩種情況都驗(yàn)證

params:額外參數(shù),當(dāng)驗(yàn)證規(guī)則類型為function,callback等時(shí)用到


1.TP里定義的驗(yàn)證方式有哪些呢?

function,callback函數(shù)或回掉方法驗(yàn)證

confirm驗(yàn)證兩個(gè)字段的值是否相同

unique唯一性驗(yàn)證

in, not in指定范圍驗(yàn)證,逗號(hào)分隔字符串后數(shù)組

between, not between指定范圍驗(yàn)證

equal, notequal值等于或不等于驗(yàn)證

length長(zhǎng)度驗(yàn)證

expire有效期驗(yàn)證

ip_allow,ip_deny IP驗(yàn)證

regex:正則驗(yàn)證

2.正則驗(yàn)證TP里定義的有哪些?

 'require'   =>  '/\S+/', //是否為空
 'email'     =>  '/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/' , //email驗(yàn)證規(guī)則
 'url'       =>  '/^http(s?):\/\/(?:[A-za-z0-9-]+\.)+[A-za-z]{2,4}(:\d+)?(?:[\/\?#][\/=\?%\-&~`@[\]\':+!\.#\w]*)?$/' , //url規(guī)則
 'currency'  =>  '/^\d+(\.\d+)?$/' , //貨幣規(guī)則
 'number'    =>  '/^\d+$/' , //數(shù)字驗(yàn)證規(guī)則
 'zip'       =>  '/^\d{6}$/', //
 'integer'   =>  '/^[-\+]?\d+$/' , //×××驗(yàn)證規(guī)則
 'double'    =>  '/^[-\+]?\d+(\.\d+)?$/' , //double類型規(guī)則
 'english'   =>  '/^[A-Za-z]+$/' , //英文字母驗(yàn)證

3.源碼分析

①自動(dòng)表單驗(yàn)證方法 autoValidation

TP里當(dāng)調(diào)用create方法時(shí)會(huì)自動(dòng)調(diào)用該方法進(jìn)行自動(dòng)驗(yàn)證,首先看該方法的這一段:

 if( empty ($val[5]) || ( $val[5]== self:: MODEL_BOTH && $type < 3 ) || $val[5]== $type ) {
     ......
     }

這里判斷是否需要執(zhí)行驗(yàn)證,如果驗(yàn)證時(shí)間為空,或者驗(yàn)證時(shí)間為3(插入和更新時(shí)都驗(yàn)證)或者驗(yàn)證時(shí)間等于給定的參數(shù)$type(1,2)則驗(yàn)證,舉個(gè)例子

protected $_validate = array(
     array('title','require','title can not be blank'); //$val[5]為空
     array('title','','title should be uqiue',1,'unique',1);

);

例如:if($model->create($data,1)){ .... },那么此時(shí)表示插入時(shí)驗(yàn)證,傳入2表示更新時(shí)驗(yàn)證,那么$_validate里有對(duì)應(yīng)的$val[5]值得規(guī)則就會(huì)被驗(yàn)證

再來看下驗(yàn)證條件

// 判斷驗(yàn)證條件

 switch ($val[3]) {
    case self ::MUST_VALIDATE :   // 必須驗(yàn)證 不管表單是否有設(shè)置該字段
     if (false === $this->_validationField($data,$val))
          return false ;
   break ;
   case self ::VALUE_VALIDATE :    // 值不為空的時(shí)候才驗(yàn)證
       if ('' != trim($data[$val[0]]))
          if (false === $this->_validationField($data,$val))
              return false ;
   break ;
    default :    // 默認(rèn)表單存在該字段就驗(yàn)證
      if (isset ($data[$val[0]]))
        if (false === $this->_validationField($data,$val))
              return false ;
     }

這里Model.class.php類里定義了6個(gè)常量,分別是:

const MODEL_INSERT          =   1;      //  插入模型數(shù)據(jù)
const MODEL_UPDATE          =   2;      //  更新模型數(shù)據(jù)
const MODEL_BOTH            =   3;      //  包含上面兩種方式
const MUST_VALIDATE         =   1;      // 必須驗(yàn)證
const EXISTS_VALIDATE       =   0;      // 表單存在字段則驗(yàn)證
const VALUE_VALIDATE        =   2;      // 表單值不為空則驗(yàn)證

上面的代碼表示$val[3]如果為1時(shí),必須驗(yàn)證 為2時(shí),表單字段的值不為空時(shí)才驗(yàn)證,默認(rèn)是存在該字段就驗(yàn)證。

②好,那么下面來分析下具體是怎么驗(yàn)證的?

_validationField方法傳入了兩個(gè)參數(shù),一是表單提交的數(shù)組$data,二是驗(yàn)證規(guī)則數(shù)組

仔細(xì)分析下該方法里的這段代碼:

 if( false === $this->_validationFieldItem($data,$val)){
     if ($this->patchValidate ) {//批量驗(yàn)證
          $this-> error[$val[0]]   =   $val[2];
      } else {//單個(gè)驗(yàn)證
          $this-> error    =   $val[2];
             return false ;
      }
  }

這里$this->patchValidate表示是否批量處理驗(yàn)證,如果為true,則驗(yàn)證不通過時(shí)返回的錯(cuò)誤信息為一數(shù)組,否則就行單個(gè)驗(yàn)證,返回的錯(cuò)誤信息為字符串。

③驗(yàn)證方式

_validationFieldItem方法里定義了常見的驗(yàn)證方式,像function,callback,unique,confirm等這些驗(yàn)證,否則檢查附加規(guī)則

switch (strtolower(trim($val[4]))) {
   case 'function': // 使用函數(shù)進(jìn)行驗(yàn)證
   case 'callback': // 調(diào)用方法進(jìn)行驗(yàn)證
     $args = isset ($val[6])?(array)$val[6]: array();
     if (is_string($val[0]) && strpos($val[0], ',' ))
       $val[0] = explode( ',', $val[0]);
       if (is_array($val[0])){
         // 支持多個(gè)字段驗(yàn)證
         foreach ($val[0] as $field)
           $_data[$field] = $data[$field];
             array_unshift($args, $_data);
       } else {
            array_unshift($args, $data[$val[0]]);
       }
       if ('function' ==$val[4]) {
           return call_user_func_array($val[1], $args);
        } else {
           return call_user_func_array( array(&$this, $val[1]), $args);
       }
                 ......
     default :  // 檢查附加規(guī)則
       return $this->check($data[$val[0]],$val[1],$val[4]);
   }

     附加規(guī)則方法check里定義里常見的像in,not in,between,not between,equal等驗(yàn)證方式,如果不符合這些驗(yàn)證方式的話,默認(rèn)為regex正則驗(yàn)證

④正則驗(yàn)證

TP里把驗(yàn)證規(guī)則分別定義到了三個(gè)方法里,_validationFieldItem里定義了像function,unique這些驗(yàn)證規(guī)則,check里定義了in,not in等常見的附加規(guī)則,這些都不滿足的話則調(diào)用regex方法進(jìn)行正則驗(yàn)證

$validate = array(
     'require'   =>  '/\S+/' ,
     'email'     =>  '/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/' ,
     'url'       =>  '/^http(s?):\/\/(?:[A-za-z0-9-]+\.)+[A-za-z]{2,4}(:\d+)?(?:[\/\?#][\/=\?%\-&~`@[\]\':+!\.#\w]*)?$/' ,
     'currency'  =>  '/^\d+(\.\d+)?$/' ,
     'number'    =>  '/^\d+$/' ,
     'zip'       =>  '/^\d{6}$/',
     'integer'   =>  '/^[-\+]?\d+$/' ,
     'double'    =>  '/^[-\+]?\d+(\.\d+)?$/' ,
     'english'   =>  '/^[A-Za-z]+$/' ,
     );
     // 檢查是否有內(nèi)置的正則表達(dá)式
     if (isset ($validate[strtolower($rule)]))
       $rule       =   $validate[strtolower($rule)];
     return preg_match($rule,$value)===1;


從源碼里可以看出TP自己定義了一些正則驗(yàn)證的規(guī)則,如果不滿足這些,那么就要傳入自定義的正則表達(dá)式,最后執(zhí)行preg_match($rule,$value)===1


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI