近日使用TP3.1版本的自動驗證發現有BUG,主要表現爲:自動驗證update編輯更新的時候如果唯一字段沒有變化也會報數據庫重複錯誤提示
/*
最後第六個參數比較詭異
填1的時候,ADD驗證SAVE都驗證
填2的時候,ADD和SAVE都不進去驗證
填3的時候,ADD驗證SAVE都驗證
create驗證的時候第二個參數傳遞self::MODEL_UPDATE或者2時,
填1時,add驗證save不驗證,
填2時,add不驗證save驗證,
填3時,add驗證save驗證,
create驗證的時候第二個參數傳遞self::MODEL_INSERT或者1時,
填1時,add驗證save驗證,
填2時,add不驗證save不驗證,
填3時,add驗證save驗證,
create驗證的時候第二個參數傳遞self::MODEL_BOTH或者3時,
填1時,add不驗證save不驗證,
填2時,add不驗證save不驗證,
填3時,add驗證save驗證,
這些數據怎麼來的可以參考核心代碼Model.class.php中autoValidation方法的 if(empty($val[5]) || $val[5]== self::MODEL_BOTH || $val[5]== $type )這個判斷,在918行左右。
$val[5]就是你傳遞進去的自動驗證的第6個參數,$type就是create時傳遞進去的第二個參數如果不傳他會自己判斷判斷方法可參考create方法的$type = $type?$type:(!empty($data[$this->getPk()])?self::MODEL_UPDATE:self::MODEL_INSERT);在749行左右。
*/
平時的寫法卻在只需要更新數據時自動驗證的時候自動驗證不驗證的例子:
protected $_validate = array(
array('user_name', 'checkupdate', '該賬號已關聯嘉賓,一個賬號只能關聯一個嘉賓資料', 0,'callback',2),
);
//驗證編輯
protected function checkupdate($data){
$id=trim($_POST['id']);
if($this->where("id!=".$id." and user_name='".trim($data)."'")->find()){
return false;
}else{
return true;
}
}
//編輯執行
public function update(){
$data['user_name']=trim($_POST['user_name']);
$data['pen_name']=trim($_POST['pen_name']);
$data['price']=trim($_POST['price']);
$data['guests_jj']=trim($_POST['guests_jj']);
$data['guests_info']=trim($_POST['guests_info']);
$data['status']=1;
$data['createtime']=time();
if( $this->create( $data ) ) {
return $this->where('id='.$_POST['id'])->save();
} else {
return $this->getError();
}
}
正確使用的例子,這樣寫後只會在更新的時候驗證:
protected $_validate = array(
array('user_name', 'checkupdate', '該賬號已關聯嘉賓,一個賬號只能關聯一個嘉賓資料', 0,'callback',2),
);
//驗證編輯
protected function checkupdate($data){
$id=trim($_POST['id']);
if($this->where("id!=".$id." and user_name='".trim($data)."'")->find()){
return false;
}else{
return true;
}
}
//編輯執行
public function update(){
$data['user_name']=trim($_POST['user_name']);
$data['pen_name']=trim($_POST['pen_name']);
$data['price']=trim($_POST['price']);
$data['guests_jj']=trim($_POST['guests_jj']);
$data['guests_info']=trim($_POST['guests_info']);
$data['status']=1;
$data['createtime']=time();
//此處紫色部分可用self :: MODEL_UPDATE或者2
if( $this->create( $data , self :: MODEL_UPDATE) ) {
return $this->where('id='.$_POST['id'])->save();
} else {
return $this->getError();
}
}
PS:造成這個BUG的原因是因爲我們的數據$data中沒有主鍵字段的存在,create是根據$data中的字段來判斷是添加操作還是更新操作的,如果有主鍵字段他會認爲是更新驗證,沒有主鍵字段就認爲是添加驗證。所以$data數組中有主鍵字段的就可以在create時不傳第二個參數,上面自動驗證第六個參數直接填2就可以達到所要的效果了