Составленный запрос MySQL работает, но если параметризованный в MySQL не работает
У меня есть страница поиска с 3 терминами (параметр поиска, почтовый индекс и вид деятельности)
Я сделал функцию для создания 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 правильно составлен, вы вводите любой параметр или ничего и возвращаете массив элементов.
Я хочу сделать параметризованный запрос, и это мой подход:
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()), что будет возможно, если я не связываю результаты нормально, выполнение не возвращает никаких результатов.
Я также пытался сделать:
/* 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,$activity) для вызова call_user_func_array():
call_user_func_array(array(&$stmt, 'bind_param'), $data);
Я также пытаюсь:
call_user_func_array(array($stmt, 'bind_param'), $data);
И этот подход до сих пор не возвращает данных.
Что я могу попробовать сейчас, чтобы заставить его работать с параметризованными запросами?
Любая помощь будет приветствоваться:D
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);