天天看點

think php in,ThinkPhp3.2中的not in Bug

有時候在一些比較老的系統中做開發,用的thinkphp3.2架構。

不得不說,thinkphp有它的優點 ,但也發現了不少缺陷。比如今天說的,就是進行sql查詢時的bug。

thinkphp支援where函數傳入查詢條件,當我要查詢id在,或者不在一些數組裡面的時候,代碼可以這麼寫:

$ids = array();

$data = M('User')->where(array(

'id'=>array('not in',$ids)

))->select();

注意,這裡的$ids是一個空數組。這種情況,無論是not in,還是in,thinkphp拼裝出來的sql是這樣的:

SELECT * FROM `user` WHERE `id` NOT IN () ;

而這樣的sql語句運作是會報錯的。作為一個架構,在傳入參數都合法的情況下,竟然生成一條報錯的sql,實在是不應該。

正确的SQL應該是這樣的:

SELECT * FROM `user` WHERE `id` NOT IN ('') ;

是以,我對ThinkPhp3.2架構的DB層進行了簡單的修改。

在Common/ThinkPHP/Library/Think/Db/Driver.class.php的parseWhereItem方法裡,可以找到這樣的代碼:

}elseif(preg_match('/^(notin|not in|in)$/',$exp)){ // IN 運算

if(isset($val[2]) && 'exp'==$val[2]) {

$whereStr .= $key.' '.$this->exp[$exp].' '.$val[1];

}else{

if(is_string($val[1])) {

$val[1] = explode(',',$val[1]);

}

$zone = implode(',',$this->parseValue($val[1]));

$whereStr .= $key.' '.$this->exp[$exp].' ('.$zone.')';

}

}

我簡單的修改後,變成了:

}elseif(preg_match('/^(notin|not in|in)$/',$exp)){ // IN 運算

if(isset($val[2]) && 'exp'==$val[2]) {

$whereStr .= $key.' '.$this->exp[$exp].' '.$val[1];

}else{

if(is_string($val[1])) {

$val[1] = explode(',',$val[1]);

}

$zone = implode(',',$this->parseValue($val[1]));

if(empty($zone)){

$whereStr .= $key.' '.$this->exp[$exp].' (\'\')';

}else{

$whereStr .= $key.' '.$this->exp[$exp].' ('.$zone.')';

}

}

}

這樣,即使傳入一個空數組,也不會報錯,而且還會傳回你想要的查詢結果。