2013-02-23 1 views
0

У меня есть страница поиска с 3 триместра (параметр Seach, почтовый индекс и тип деятельности)состоит MySQL запрос работает, но если параметризованных в MySQLi не работает

Я сделал функцию, чтобы составить SQL: (это не настоящая функция, просто упрощенная). Вы можете использовать его с параметрами (-ами), которые вы хотите фильтровать или без параметра, чтобы получить все.

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 правильно составлен, вы помещаете любой параметр или none и возвращаете массив элементов.

Я хочу сделать параметризованных запросов, и это мой подход:

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 Array() не Array (Array(), Array()), что будет возможно, если я не привяжу результаты ok, выполнение не возвращает никаких результатов.

Я также попытался сделать:

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

Чтобы создать массив типа ('СКУ', $ S $ POST_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

ответ

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 (я не буду делать одну строку соединения только для одной функции) , Спасибо –

+0

вы можете использовать [safemysql] (https://github.com/colshrapnel/safemysql/blob/master/safemysql.class.php). он позволит вам создавать условные запросы и использовать mysqli. Я приведу пример моего ответа. –

+0

Я попробую, но я не понимаю, почему не работает мой параметризованный запрос. –

Смежные вопросы