Функция не работает с большим количеством параметров

Это моя функция:

    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.

1

Решение

Проблема в том, что вы используете bindParam() для переменной, которая меняет свое значение:

foreach ($parameters as $key => $parameter) {
$result->bindParam($key, $parameter);
}

Вы должны понимать, что bindParam() связывает переменная по ссылке, а не значение, которое переменная имеет в то время, когда вы делаете привязку.

Вы связываете переменную $parameter к обоим параметрам в вашем запросе. Значение не отправляется, пока вы не позвоните execute(), Таким образом, он отправляет значение, которое переменная имеет после завершения цикла, которое является паролем.

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

140905 10:09:45    49 Connect   root@192.168.56.1 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(),

0

Другие решения

Ваши параметры должны выглядеть как массив

$parameters = [
"key"   =>  "parameter",
"key2 " =>  "parameter2"];

Тогда Вы пропустили пароль

$db = new PDO("mysql:host=localhost;dbname=cms","root","your_password");

Моя идея взглянуть на PDOStatement :: bindParam Docs

0