Используйте директиву IN для поиска с подготовленным заявлением

Моя цель – найти все элементы в таблице, которые соответствуют коллекции, хранящейся в String:

$array=array("item1","item2","item3","item4");//This is dynamically filled, this is just an example $in_list = "'".implode("','",$array)."'";//that's why i use implode $stmt = $this->db->prepare('SELECT libelle,activite,adresse,tel,lat,lng FROM etablissements where type IN ('.$in_list.')'); $stmt->bind_param("s", $in_list); $stmt->execute(); $stmt->bind_result($libelle,$activite,$adresse,$tel,$lat,$lng); 

Кажется, что это не работает отлично, оно всегда бросает мне следующее предупреждение:

 mysqli_stmt::bind_param() [<a href='mysqli-stmt.bind-param'>mysqli-stmt.bind-param</a>]: Number of elements in type definition string doesn't match number of bind variables in <b>/homepages/25/d399726988/htdocs/ 

Если бы у меня был один параметр, было бы очевидно:

  $stmt = $this->db->prepare('SELECT libelle,activite,adresse,tel,lat,lng FROM etablissements where type =?'); $stmt->bind_param("s", $parameter); 

Но поскольку я должен иметь дело с этим, мне стало немного сложно.

Подготовленный оператор не имеет параметров, потому что перед его подготовкой вы интерполировали список в инструкцию.

 $array=array("item1","item2","item3","item4"); //This is dynamically filled, this is just an example $in_list = "'".implode("','",$array)."'";//that's why i use implode $stmt = $this->db->prepare('SELECT libelle,activite,adresse,tel,lat,lng FROM etablissements where type IN ('.$in_list.')'); 

На этом этапе созданный вами SQL-оператор:

 SELECT libelle,activite,adresse,tel,lat,lng FROM etablissements where type IN ('item1','Item2','Item3','Item4') 

Поскольку оператор не имеет параметров, mysqli_stmt::bind_param терпит неудачу. Вместо того, чтобы интерполировать элементы в оператор (который уязвим для инъекций), интерполировать строку параметров, а затем привязать значения (которые должны храниться отдельно).

 $array=array("item1","item2","item3","item4"); if (count($in_list) > 0) { $query = $this->db->prepare('SELECT libelle,activite,adresse,tel,lat,lng FROM etablissements WHERE type IN (' . str_repeat('?, ', count($in_list)-1) . '?)'); $args = $in_list; array_unshift($args, str_repeat('s', count($in_list))); call_user_func_array(array($query, 'bind_param'), $args); $query->execute(); $query->bind_result($libelle,$activite,$adresse,$tel,$lat,$lng); } 

Интерфейс PDO для привязки более прост.

 $array=array("item1","item2","item3","item4"); if (count($in_list) > 0) { $query = $this->db->prepare('SELECT libelle,activite,adresse,tel,lat,lng FROM etablissements WHERE type IN (' . str_repeat('?, ', count($in_list)-1) . '?)'); foreach ($in_list as $i => $arg) { // query params are 1-based, so add 1 to the index // PDO::PARAM_STR is the default type, so no need to pass 3rd arg $query->bindValue($i+1, $arg); } $query->execute(); // no need to bind the result } 

Фактически, это может быть еще проще с PDO, поскольку PDOStatement::execute может принимать список значений параметров:

 $array=array("item1","item2","item3","item4"); if (count($in_list) > 0) { $query = $this->db->prepare('SELECT libelle,activite,adresse,tel,lat,lng FROM etablissements WHERE type IN (' . str_repeat('?, ', count($in_list)-1) . '?)'); $query->execute($in_list); }