MySQL, где в (массиве)

function delete_group($db) {
    $ids = Parameters::get('ids');
    $ids = implode(',', $ids); // now a string like '5,6,7'.
    add_to_log($ids);
    try {
        $stmt = $db->prepare("DELETE FROM mytable WHERE id IN (:ids)");
        $stmt->bindParam(':ids', $ids, PDO::PARAM_STR);
        $stmt->execute();
        response('success', 'success', NULL);
    }
    catch (PDOException $e) {
        response('error', 'Delete group failed.', NULL);
    }
}

Этот код не работает: удаляется только первая строка. Но если я сделаю

$stmt = $db->prepare("DELETE FROM mytable WHERE id IN ($ids)");

вместо этого (просто вставьте строку) он работает, хотя в коде есть проблема с безопасностью SQL-инъекций. Как заставить его работать и обезопасить?


person noober    schedule 05.01.2014    source источник
comment
Вы не можете этого сделать. Вам нужно связать их по отдельности; Привязанные параметры SQL не являются произвольными интерполяциями/конкатенациями переменных, а скорее отдельными значениями, передаваемыми в тех местах, где они приняты.   -  person Michael Berkowski    schedule 06.01.2014
comment
Если я правильно помню, PHP PDO не поддерживает WHERE IN для подготовленных операторов. Вам придется проделать дополнительную работу, чтобы настроить его (либо создать параметры X ? в зависимости от размера массива, либо выполнить implode() для массива).   -  person Sam    schedule 06.01.2014


Ответы (1)


$ids = Parameters::get('ids');
$ids = array_map('intval', $ids);
$ids = implode(',', $ids);

Теперь вам не нужно беспокоиться об инъекциях.

person Jessica    schedule 05.01.2014
comment
Это лучший ответ из всех на оба вопроса, указанные выше. - person noober; 06.01.2014
comment
@noober Это может быть короткое решение, но оно действительно только для целых идентификаторов. Для строковых значений это тоже можно сделать, но не рекомендуется смешивать связанные параметры и экранированные строки в большом запросе. Связанные параметры в подготовленных операторах являются общепринятой передовой практикой, даже если количество строк значительно увеличивается. - person Michael Berkowski; 06.01.2014
comment
@MichaelBerkowski Никогда не видел нецелые идентификаторы. - person noober; 06.01.2014
comment
@noober Это не означает, что их не существует или что предложение IN () используется только в столбцах id PK. - person Michael Berkowski; 06.01.2014
comment
Так как комментарий был // теперь строкой вроде '5,6,7'. Я собираюсь предположить, что они целые числа. - person Jessica; 06.01.2014