Positional parameters in SQL start at 1. You process this by binding $i+1 to the position in your loop.
But then you bind the last parameter for cidades_codigo to the position count($options) , which overwrites the last parameter given in the $ options loop.
You need to bind the last parameter to the position count($options)+1 .
FWIW, you don't need bindValue() at all. It's easier to just pass an array of execute() parameters. This is how I will write this function:
public function getCompaniesByCity(City $city, $options = null) { $database = Connection::getConnection(); $sql = "SELECT * FROM `empresas` WHERE `empresas`.`cidades_codigo` = ?" $params = array(); $params[] = $city->getId(); if ($options) { $sql .= " AND `prods_empresas`.`produtos_codigo` IN (" . join(",", array_fill(1, count($options), "?") . ")"; foreach ((array)$options as $option) { $params[] = $option->getId(); } } $statement = $database->prepare($sql); echo $sql; $statement->execute($params); . . .
Also, don't forget to check the return value of prepare() and execute() , it will be false if there is an error, and you need to check this and report the error. Or else enable PDO to throw exceptions on error.
Bill karwin
source share