Моя цель – найти все элементы в таблице, которые соответствуют коллекции, хранящейся в 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); }