Это моя функция:
function countRows($sql, $parameters){
$db = new PDO("mysql:host=localhost;dbname=cms","root");
$result = $db->prepare($sql);
foreach ($parameters as $key => $parameter) {
$result->bindParam($key, $parameter);
}
$result->execute();
$number_of_rows = $result->fetchAll();
return count($number_of_rows);
}
С таким массивом $ parameters он работает просто отлично:
$parameters=array("key"=>"parameter");
Но когда массив имеет больше ключей и переменных, он просто даст результат 0
Например, с таким массивом это дает мне 0 строк, когда должно быть 3
$parameters=array("key"=>"parameter", "key2"=>"parameter2");
Редактировать:
Пример запроса:
"SELECT * FROM users WHERE username=:username AND password=:password"
Пример $ параметров для этого запроса:
$parameters = array(":username"=>$username, ":password"=>$password);
Когда я запускаю его с одним столбцом (например, только имя пользователя или только пароль), он работает нормально, с обоими он всегда возвращает 0.
Проблема в том, что вы используете bindParam()
для переменной, которая меняет свое значение:
foreach ($parameters as $key => $parameter) {
$result->bindParam($key, $parameter);
}
Вы должны понимать, что bindParam()
связывает переменная по ссылке, а не значение, которое переменная имеет в то время, когда вы делаете привязку.
Вы связываете переменную $parameter
к обоим параметрам в вашем запросе. Значение не отправляется, пока вы не позвоните execute()
, Таким образом, он отправляет значение, которое переменная имеет после завершения цикла, которое является паролем.
Я проверил это, включив общий журнал запросов на моем сервере MySQL и наблюдая за тем, что регистрируется:
140905 10:09:45 49 Connect [email protected] on test
49 Prepare SELECT * FROM users WHERE username=? AND password=?
49 Execute SELECT * FROM users WHERE username='password' AND password='password'
49 Close stmt
49 Quit
Вы можете решить это одним из двух способов:
использование bindValue()
вместо bindParam()
, Это копирует значение $parameter
в то время, когда вы делаете привязку.
В качестве альтернативы, вам не нужно делать цикл для привязки параметров по одному, просто передайте массив execute()
:
$result->execute($parameters);
Я не знаю, почему так много разработчиков считают, что им нужно писать код для привязки параметров по одному. Проще передать массив параметров напрямую execute()
,
Ваши параметры должны выглядеть как массив
$parameters = [
"key" => "parameter",
"key2 " => "parameter2"];
Тогда Вы пропустили пароль
$db = new PDO("mysql:host=localhost;dbname=cms","root","your_password");
Моя идея взглянуть на PDOStatement :: bindParam Docs