Web

Передача массива в запрос с помощью предложения WHERE

У меня есть массив идентификаторов, $galleries = array(1,2,5), и я хочу создать SQL-запрос, который использует значения массива в своем предложении WHERE, например:

SELECT *

FROM galleries

WHERE id = /* значения из массива $galleries... eg. (1 || 2 || 5) */

Как я могу сгенерировать эту строку запроса для использования с MySQL?

 

Ответ 1

Использование PDO: 

$in = join(',', array_fill(0, count($ids), '?'));

$select = <<<SQL

    SELECT *

    FROM galleries

    WHERE id IN ($in);

SQL;

$statement = $pdo->prepare($select);

$statement->execute($ids);

 

Использование MySQLi:

$in = join(',', array_fill(0, count($ids), '?'));

$select = <<<SQL

    SELECT *

    FROM galleries

    WHERE id IN ($in);

SQL;

$statement = $mysqli->prepare($select);

$statement->bind_param(str_repeat('i', count($ids)), ...$ids);

$statement->execute();

$result = $statement->get_result();

 

Объяснение:

Используйте IN() оператор SQL, чтобы проверить, существует ли значение в данном списке.

В целом это выглядит так:

expr IN (value,...)

Мы можем создать выражение, которое будет помещено внутрь нашего массива. Обратите внимание, что внутри скобок должно быть хотя бы одно значение, иначе MySQL вернет ошибку; это равносильно тому, чтобы в нашем входном массиве было хотя бы одно значение. Чтобы предотвратить атаки с использованием SQL-инъекций, сначала сгенерируйте «для каждого элемента ввода, чтобы создать параметризованный запрос. Здесь я предполагаю, что массив, содержащий ваши идентификаторы, называется $ids:

$in = join(',', array_fill(0, count($ids), '?'));

$select = <<<SQL

    SELECT *

    FROM galleries

    WHERE id IN ($in);

SQL;

Учитывая, что входной массив из трех элементов $select будет выглядеть так:

SELECT *

FROM galleries

WHERE id IN (?, ?, ?)

Снова обратите внимание, что «для каждого элемента во входном массиве есть. Затем мы будем использовать PDO или MySQLi для подготовки и выполнения запроса, как указано выше.

Использование IN() оператора со строками.

Из-за связанных параметров легко переключаться между строками и целыми числами. Для PDO никаких изменений не требуется; для MySQLi измените str_repeat('i', на, str_repeat('s', если вам нужно проверять строки.

 

Ответ 2

Для MySQLi с функцией escape:

$ids = array_map(function($a) use($mysqli) { 

    return is_string($a) ? "'".$mysqli->real_escape_string($a)."'" : $a;

  }, $ids);

$ids = join(',', $ids);  

$result = $mysqli->query("SELECT * FROM galleries WHERE id IN ($ids)");

 

Для PDO с подготовленным выражением:

$qmarks = implode(',', array_fill(0, count($ids), '?'));

$sth = $dbh->prepare("SELECT * FROM galleries WHERE id IN ($qmarks)");

$sth->execute($ids);

 

Ответ 3

Мы должны позаботиться об уязвимостях SQL-инъекций и null состоянии. Для числового массива используйте соответствующее преобразование типа, а именно intval, floatval или doubleval для каждого элемента. Для строковых типов, mysqli_real_escape_string(), которые при желании также могут применяться к числовым значениям. MySQL допускает числа, а также варианты даты в виде строки .

Чтобы соответствующим образом избежать значений перед переходом к запросу, создайте функцию, подобную этой:

function escape($string) {

    // Предполагается, что $db это идентификатор ссылки, возвращенный mysqli_connect() или mysqli_init()

    return mysqli_real_escape_string($db, $string);

}

Такая функция, скорее всего, уже будет доступна вам в вашем приложении или, может быть, вы уже ее создали.

Очистите массив строк, например:

$values = array_map('escape', $gallaries);

Числовой массив можно обезопасить, используя intval, floatval или doubleval:

$values = array_map('intval', $gallaries);

 Затем, наконец, создайте where запроса:

$where  = count($values) ? "`id` = '" . implode("' OR `id` = '", $values) . "'" : 0;

 или же

$where  = count($values) ? "`id` IN ('" . implode("', '", $values) . "')" : 0;

Поскольку массив также иногда может быть пустым, $galleries = array(); поэтому необходимо быть уверенным в наличие значений, так как IN() не допускает пустой список. Можно также использовать OR вместо этого, но проблема остается.

И добавляем в финальный запрос:

$query  = 'SELECT * FROM `galleries` WHERE ' . $where;

 

Схожие статьи

Web

Создание шаблона проектирования Singleton в PHP5

Что такое промышленный интернет вещей: особенности, преимущества и недостатки
Web

Что такое промышленный интернет вещей: особенности, преимущества и недостатки

Web

Множественные выходы из функции

Web

Использование JQuery Ajax для получения данных из Mysql

×