2013-02-23 102 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