УрокБезопасный SQL запрос к базе данных в секции IN при работе с динамическими данными

В Друпал 6 значения, подставляемые в sql запрос могут заменяться %f, %d, %s. Однако что делать, если надо передать в запрос массив данных, который использует секцию IN? Пример:

$result = db_query('SELECT title FROM {node} WHERE nid IN (1, 10, 25)');

Если значения nid заранее известны то проблем не возникает - просто пользуемся вариантом выше и получаем профит. Однако, если количество передаваемых значений не известно, то могут возникнуть трудности. Конечно, можно было бы сделать так:

$nids_array = array(1, 10, 25);
$nids = implode(',', $nids_array);
$result = db_query('SELECT title FROM {node} WHERE nid IN (' . $nids . ')');

Однако этот вариант нельзя использовать из-за его небезопасности (sql-инъекции ещё никто не отменял).

Поэтому делаем вот такой нехитрый финт ушами:

$nids_array = array(1, 10, 25);
$placeholders = array_fill('%d', count($nids_array));
$placeholders = implode(',', $placeholders);
$result = db_query("SELECT title FROM {node} WHERE nid IN ($placeholders)", $nids_array);

В итоге в секцию IN будут переданы значения %d, которые являются гарантом безопасного запроса к базе данных.

Для этих же целей можно использовать функцию db_placeholders():

$nids_array = array(1, 10, 25);
$result = db_query("SELECT title FROM {node} WHERE nid IN (" . db_placeholders($nids_array) . ")", $nids_array);

Кстати, в Drupal 7 это решается совсем просто:

$nids_array = array(1, 10, 25);
$result = db_query('SELECT title FROM {node} WHERE nid IN (:nids)', array(':nids' => $nids_array));

Комментарии

Аватар пользователя xandeadx
xandeadx написал:

не учи плохому!)
http://api.drupal.org/api/drupal/includes--database.inc/function/db_placeholders/6

02.12.2011 22:55
Аватар пользователя Spleshka
Spleshka написал:

Подстава, я не знал про эту функцию :/ Но она делает то же, что я сказал)

03.12.2011 01:03
Аватар пользователя Spleshka
Spleshka написал:

Дополнил статью с db_placeholders().

05.12.2011 17:32

Комментировать