PDO bindParam не работает в привязке IN для запроса sql

Я пытаюсь получить 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());
?>
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
0
139
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Измените bindParam на bindValue

Если вы хотите использовать bindParam, измените свой sql на

u.age <= :age and
YEAR(v.upload_date) >= :year
...

Затем привяжите параметр:

->bindParam(':age', $age)
->bindParam(':year', $year)

Как насчет заявления IN?

Aman 29.05.2019 05:15

Нельзя использовать bindParam с предложением IN. Вместо этого можно использовать bindValue или внедрить в sql u.country NOT IN ('" . implode("','", $countries) . "')

user9032546 29.05.2019 06:13
Ответ принят как подходящий

Ваша проблема в том, что вы привязываете все параметры IN к одной и той же переменной ($x), поэтому все они получают одно и то же значение. Вы можете обойти это, либо изменив на bindValue, либо привязав к фактическому значению массива, т.е.

$statement->bindParam($k+3, $countries[$k], PDO::PARAM_STR);

$x присваивается в цикле foreach... поэтому он должен быть таким же, как $countries[$k]

Tim Morton 28.05.2019 14:37

@TimMorton да, это значение такое же (поэтому замена на bindValue будет работать), но bindParam формирует ссылку на Переменная, поэтому в конце цикла все связанные параметры будут указывать на одно и то же, и все получат такое же значение.

Nick 29.05.2019 00:50

Вау, это сработало. Хотя я не понимаю, почему мой код в вопросе не работает. $x должно иметь то же значение, что и $countries[$k].

Aman 29.05.2019 05:23

@Aman, посмотри мой предыдущий комментарий Тиму Мортону. bindParam формирует ссылку на переменную, поэтому все ваши параметры привязаны к $x, и когда вы выполняете запрос, он имеет последнее значение в массиве countries, что означает, что вы фактически игнорируете другие значения в массиве.

Nick 29.05.2019 06:51

@Ник Спасибо за объяснение. Ссылка вместо значения... Я полностью пропустил какие-либо подсказки, указывающие на это.

Tim Morton 29.05.2019 15:45

Другие вопросы по теме