WHERE запрос с IN в Mysqli — как?

Рейтинг: 0Ответов: 2Опубликовано: 05.05.2015

Привет всем.

В общем проблема следующая:
Есть запрос:

$query = $mysqli->prepare('SELECT id FROM Publication WHERE id in (?)');
    $query->bind_param('s', $field_cat);
    $query->execute();

Где $field_cat = "1,2,4";

Как я понял, благодаря bind_param, в запрос вставляется только (1). И запрос выполняется не так, как хотелось.

Нашел несколько решений с Safemysql. Я бы не хотел использовать эту библиотеку, так как уже поздно переписывать запросы. Не уже ли в mysqli нету нормального решения?

Возможно ли сделать запрос без Prepared Statements?

Ответы

▲ 1Принят

Не уже ли в mysqli нету нормального решения?

Нет.
Если делать канонически, то есть байндить все переменные через плейсхолдеры, то у нас наберется аккурат на экран кода!

Варианты сделать запрос без Prepared Statements и вместо них слепить из жувачки какие-то костыли, разумеется, АБСОЛЮТНО не годятся. Какой смысл было переходить на mysqli, если продолжать говнокодить в стиле mysql_* из прошлого века?

Поэтому я бы рекомендовал все же использовать Safemysql. Тем более, что количество кода сократится минимум в 5 раз - там, где mysqli нужно 5 строчек, на Safemysql нужна будет только одна. Ради одного этого стоило бы переписать.

Чтобы не быть голословным. Возьмём простейший пример получения одной переменной из запроса. Без циклов, с единственным фетчем.
raw mysqli:

$query = $mysqli->prepare('SELECT id FROM Publication WHERE cat=?');
$query->bind_param('s', $field_cat);
$query->execute();
$query->bind_result($id);
$query->fetch();

safemysql:

$id = $db->getCol('SELECT id FROM Publication WHERE cat=?s');

Как я и говорил - 5 к 1. Если же нам нужно получить массив, то соотношение еще больше увеличивается, поскольку у mysqli код прибавляется, а у safemysql остается все так же одна строчка, только меняется вызываемый метод.

Update.
Кстати, есть вариант не переписывать весь код.
Safemysql можно подключить, используя существующее соединение mysqi, вот так:

$db = new SafeMySQL(['mysqli' => $mysqli]);

Таким образом, после соединения с mysql можно приинклюдить Safemysql, создать инстанс, и использовать его наряду с mysqli без каких бы то ни было лишних накладных расходов.

Таким образом искомый код сведется к

$ids = $db->getCol('SELECT id FROM Publication WHERE id IN (?a)', $field_cat);

(следует помнить, что для плейсхолдера ?a нужно передавать массив, а не строку "1,2,4")

А в дальнейшем можно будет постепенно переписать и остальные запросы более оптимальным образом.

▲ 1

Действительно, подготовленные запросы в mysqli сделаны настолько неудобно, что пользоваться ими не хочется.

Я предпочитаю использовать класс-обертку, который прячет от меня особенности конкретного расширения + добавляет вкусняшки вроде подстановки массива в IN().

Варианты работы с массивом для mysqli и PDO: https://stackoverflow.com/questions/907806/php-mysql-using-an-array-in-where-clause/29653461#29653461