My purpose is to find all the item in the table that match a collection stored in a 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);
That seems not to work perfectly, it always throwing me the following warning:
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/
If i had one parameter, it would be obvious:
$stmt = $this->db->prepare('SELECT libelle,activite,adresse,tel,lat,lng FROM etablissements where type =?');
$stmt->bind_param("s", $parameter);
But since i have to deal with that, it became a bit complicated to me.
The prepared statement has no parameters because you have interpolated the list into the statement before preparing it.
$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.')');
At this point, the SQL statement you have created is:
SELECT libelle,activite,adresse,tel,lat,lng
FROM etablissements where type IN ('item1','Item2','Item3','Item4')
Since the statement has no parameters, mysqli_stmt::bind_param
fails. Instead of interpolating the items into the statement (which is vulnerable to injection), interpolate a string of parameters, then bind the values (which must be kept separate).
$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's interface for binding is more straightforward.
$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
}
In fact, it can be even simpler with PDO, since PDOStatement::execute
can take a list of parameter values:
$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);
}