2013-02-23 97 views
0

我有3個學期(SEACH參數,郵政編碼和活動類型)由MySQL查詢工作,但如果在參數化庫MySQLi不工作

我做了一個函數來構造SQL搜索頁面: (這不是真正的功能,只是簡單的功能)。您可以將它與您要過濾的參數(s)或不帶參數的參數一起使用。

function get_items($search="",$postal_code="",$activity=""){ 
global $db; //this is the $db=new mysqli(...) in other include file 
$where=""; 
if ($s!=""){ 
    $s="%".$search."%"; 
    $where=" AND ((item.name like '".$s."') OR (item.description like '".$s."'))"; 
} 
if($postal_code!=""){ 
    if (strlen($postal_code)==5){ 
     $where=" AND (item.postal_code like '".$postal_code."')"; 
    } 
} 

if($activity!=""){ 
    if (m_is_integer($postal_code)){ //m_is_integer returns true if is an integer 
     $where=" AND (item.activity =".$activity.")"; 
    } 
} 
$sql="select ....... from -..... where .....".$where." order by ......" 
//yes, I know I don't need to prepare the query 
$stmt=$db->prepare($sql); 
$result=$stmt->execute(); 
$stmt->store_result(); 
$item_array=Array(); 
if (($result!=false) && ($stmt->num_rows>0)){ 
    //do things and populate the array $item_array 
} 
$stmt->close(); 
return $item_array; 
} 

這個函數的工作原理是,sql是正確組合的,你可以放任何參數或無,並返回一個項目數組。

我想讓參數化查詢,這是我的方法:

function get_items_parametrized($search="",$postal_code="",$activity=""){ 
global $db; //this is the $db=new mysqli(...) in other include file 
$where=""; 
$bind_array=Array(); 
if ($s!=""){ 
    $s="%".$search."%"; 
    $where=" AND ((item.name like ?) OR (item.description like ?))"; 
    $bii=Array("s",$s); 
    $bind_array[]=$bii; 
    $bii=Array("s",$s); 
    $bind_array[]=$bii; 
} 
if($postal_code!=""){ 
    if (strlen($postal_code)==5){ 
     $where=" AND (item.postal_code like ?)"; 
     $bii=Array("s",$postal_code); //yes, is a string in the database 
     $bind_array[]=$bii; 
    } 
} 

if($activity!=""){ 
    if (m_is_integer($postal_code)){ //m_is_integer returns true if is an integer 
     $where=" AND (item.activity = ?)"; 
     $bii=Array("i",$activity); 
     $bind_array[]=$bii; 
    } 
} 
$sql="select ....... from -..... where .....".$where." order by ......" 
$stmt=$db->prepare($sql); 
//go to bind data to search 
$bind_type=""; 
$bind_params=Array(); 

foreach($bind_array as $b){ 
    $bind_type.=$b[0]; 
    $bind_params[]=$b[1]; 
    /* Approach 1: */ 
    $stmt->bind_param($b[0],$b[1]); 
} 
/* Approach 2: */ 
$stmt->bind_param($bind_type,$bind_params); 
$result=$stmt->execute(); 
$stmt->store_result(); 
$item_array=Array(); 
if (($result!=false) && ($stmt->num_rows>0)){ 
    //do things and populate the array $item_array 
} 
$stmt->close(); 
return $item_array; 
} 

此功能總是返回一個空$ item_array陣列()不是一個數組(陣列(),()數組)是將是可能的,如果我不綁定結果好的,執行沒有返回任何結果。

我也試着這樣做:

/* attempt 3 */ 
$data=Array(); 
$data[0]=""; 
foreach($bind_array as $b){ 
    $data[]=$b1; 
    $bind_type.=$b[0]; 
} 
$data[0]=$bind_type; 

要撰寫像( 'SSI',$ S,$ POSTAL_CODE,$活動)的陣列來電call_user_func_array():

call_user_func_array(array(&$stmt, 'bind_param'), $data); 

我也嘗試:

call_user_func_array(array($stmt, 'bind_param'), $data); 

而這種方法仍然沒有返回數據。

現在我可以嘗試什麼來使它與參數化查詢一起工作?

任何幫助將受到歡迎:d

+0

'bind_param'要求參數是引用,'call_user_func_array'不再傳遞引用。 – Barmar 2013-02-23 12:56:01

回答

1

答案很簡單:不使用的mysqli預處理語句。
準備好的語句無法使用。
改爲使用PDO
這個的答案。 Mysqli是你的問題,你必須解決它。

通過使用PDO,您的代碼縮短了3倍,並且可以工作。

如果你想堅持mysqli,另一種方法是擺脫準備好的陳述和實現自己的佔位符,但需要一些知識。但是,它可以讓您輕鬆構建條件查詢:

$w = array(); 
$where = ''; 
if ($one) $w[] = $db->parse("one = ?s",$one); 
if ($two) $w[] = $db->parse("two IN (?a)",$two); 
if ($tre) $w[] = $db->parse("tre <= ?i",$tre); 
if (count($w)) $where = "WHERE ".implode(' AND ',$w); 
$data = $db->getArr("SELECT * FROM table ?p LIMIT ?i,?i",$where, $start,$per_page); 
+0

爲'我有時間'的解決方案我會嘗試,但現在它不可能使用pdo,它在服務器中被禁用,並且所有應用程序都與mysqli(我不打算只爲一個函數創建一個連接字符串) 。謝謝 – 2013-02-23 16:21:26

+0

然後你可以使用[safemysql](https://github.com/colshrapnel/safemysql/blob/master/safemysql.class.php)。它會讓你建立條件查詢,它使用mysqli。我會以我的答案爲例。 – 2013-02-23 16:58:23

+0

我會嘗試,但我不明白爲什麼不工作我的參數化查詢。 – 2013-02-24 16:21:33