Я пытаюсь получить videos
по некоторым атрибутам (age
, year
, countries
). По какой-то причине, хотя я правильно привязываю параметры к запросу и правильно указал запрос (u.country NOT IN ($countries_count)
), я все равно получаю результаты для country = U.S.A
. Есть ли что-то работающее с моим bindParam
. Пожалуйста помоги.
<?php
$parameters = json_decode(file_get_contents('php://input'), true);
$age = $parameters["age"];
$year = $parameters["year"];
$countries = sizeof($parameters["countries"]) == 0 ? array("0") : $parameters["countries"];
$countries_count = implode(",", array_fill(0, sizeof($countries), "?"));
$sql = "SELECT
v.title, u.name
FROM
video AS v JOIN user AS u ON v.id_user = u.id
WHERE
u.age <= ? AND YEAR(v.upload_date) >= ? AND
u.country NOT IN ($countries_count);";
$connection = new PDO("mysql:host=localhost;dbname=data_base", "root", "");
$statement = $connection->prepare($sql);
$statement->bindParam(1, $age, PDO::PARAM_INT);
$statement->bindParam(2, $year, PDO::PARAM_INT);
foreach ($countries as $k => $x) {
$statement->bindParam($k+3, $x, PDO::PARAM_STR);
}
$statement->execute();
echo json_encode($statement->fetchAll());
?>
Измените bindParam на bindValue
Если вы хотите использовать bindParam, измените свой sql на
u.age <= :age and
YEAR(v.upload_date) >= :year
...
Затем привяжите параметр:
->bindParam(':age', $age)
->bindParam(':year', $year)
Нельзя использовать bindParam с предложением IN. Вместо этого можно использовать bindValue или внедрить в sql u.country NOT IN ('" . implode("','", $countries) . "')
Ваша проблема в том, что вы привязываете все параметры IN
к одной и той же переменной ($x
), поэтому все они получают одно и то же значение. Вы можете обойти это, либо изменив на bindValue
, либо привязав к фактическому значению массива, т.е.
$statement->bindParam($k+3, $countries[$k], PDO::PARAM_STR);
$x присваивается в цикле foreach... поэтому он должен быть таким же, как $countries[$k]
@TimMorton да, это значение такое же (поэтому замена на bindValue
будет работать), но bindParam
формирует ссылку на Переменная, поэтому в конце цикла все связанные параметры будут указывать на одно и то же, и все получат такое же значение.
Вау, это сработало. Хотя я не понимаю, почему мой код в вопросе не работает. $x
должно иметь то же значение, что и $countries[$k]
.
@Aman, посмотри мой предыдущий комментарий Тиму Мортону. bindParam
формирует ссылку на переменную, поэтому все ваши параметры привязаны к $x
, и когда вы выполняете запрос, он имеет последнее значение в массиве countries
, что означает, что вы фактически игнорируете другие значения в массиве.
@Ник Спасибо за объяснение. Ссылка вместо значения... Я полностью пропустил какие-либо подсказки, указывающие на это.
Как насчет заявления
IN
?