Работа с БД в Drupal 7 - урок 3 - Статические запросы (SELECT)

MySQL drupal

Наиболее общая форма запроса в Друпал это статический запрос. Статический запрос будет передан в БД дословно. Только запрос выбора (select) может быть статический.

Только в очень простых запросах следует использовать статические запросы. Вам следует использовать динамические запросы если нужно написать сложный запрос, динамически создаваемый запрос или изменяемый после выполнения.

Простой путь выполнить статический запрос через метод запроса:

<?php
$result = $conn->query("SELECT nid, title FROM {node}");
?>

Процедурная обертка предпочтительнее:

<?php
$result = db_query("SELECT nid, title FROM {node}");
?>

Вызывая db_query() как сказано выше эквивалентно следующей конструкции:

<?php
$result = Database::getConnection()->query("SELECT nid, title FROM {node}");
?>

Давайте разберем почему использовать db_query лучший вариант чем просто напрямую обращаться к объекту Database.

db_query() принимает три аргумента. Первый это строка запроса, используя заполнители (placeholders) где нужно и беря все таблицы в фигурные скобки. Второй это массив заполнителей. Третий, опциональный, это массив конфигурация  как выполнять запрос.

Префикс

В статических запросах все таблицы должны быть обернуты в {}. Это позволяет добавить префикс к названием таблиц. Префиксы позволяют устанавливать несколько сайтов в одну базу данных, при этом используя для таблиц разные префиксы, например: "site1_", "site2_".

Заполнители

Заполнители помечаются буквами туда, где должно быть вставлено значение. Разделением заполнителями запроса, мы позволяем БД разделять SQL-синтаксис и предоставленные пользователем значения, для того чтобы предотвратить SQL-инъекции.

<?php
$result = db_query("SELECT nid, title FROM {node} WHERE created > :created", array(
  ':created' => REQUEST_TIME - 3600,
));
?>

Выше код который будет выбирать все ноды созданные позже, чем час назад. Заполнитель :created будет динамически заменен на значение REQUEST_TIME - 3600, где REQUEST_TIME время выполнения запроса. Запрос может иметь сколько угодно заполнителей, однако все должны иметь уникальные имена, даже если они имеют одинаковые значения.

В зависимости от вариантов использования массив заполнителей может быть встроенным (как в примере выше) или может быть определен заранее и передан позже. Порядок в массиве не имеет значения. Заполнители начинающиеся с "db_" зарезервированы системой и не должны использоваться явно.

Заметьте, что заполнители следует оборачивать или нет в кавычки в зависимости от их типа. Так например строковые значения нужно оборачивать в кавычки, а числовые нет.

<?php
// WRONG:
$result = db_query("SELECT nid, title FROM {node} WHERE type = ':type'", array(
  ':type' => 'page',
));

// CORRECT:
$result = db_query("SELECT nid, title FROM {node} WHERE type = :type", array(
  ':type' => 'page',
));
?>

Заменители не должны быть использованы для имени таблиц или колонок. Они служат лишь для подстановки текстовых строк или числовых значений.

Массивы заменителей

Database layer Друпал включает экстра особенность заменителей. Если значения переданы через массив заменителей, то они будут автоматически преобразованы в список разделенный запятыми. Это означает, что разработчики больше не должны заботиться о подсчете сколько заменителей им нужно. Давайте рассмотрим пример:

<?php
db_query("SELECT * FROM {node} WHERE nid IN (:nids)", array(':nids' => array(13, 42, 144));

// Подставляем массив заменителей:
db_query("SELECT * FROM {node} WHERE nid IN (:nids_1, :nids_2, :nids_3)", array(
  ':nids_1' => 13,
  ':nids_2' => 42,
  ':nids_3' => 144,
));
// Что идентично следующему запросу:
db_query("SELECT * FROM {node} WHERE nid IN (13, 42, 144)");
?>

Параметры запроса

Третья часть db_query() параметры запроса - это массив параметров, которые напрямую указывают как запрос должен быть обработан. Обычно только два параметра используются чаще других. Остальные параметры применяются для внутреннего использования.
Ключ "цель" определяет для какой цели используется запрос. Если он не указан, то используется "default". В настоящее время только корректное значение "slave" показывает что запрос должен обрабатываться на slave сервере, если он существует. Ключ "fetch" показывает каким образом записи будут возвращены от БД. Значения параметров запросов включают: PDO::FETCH_OBJ, PDO::FETCH_ASSOC, PDO::FETCH_NUM, PDO::FETCH_BOTH или строка представляющая имя класса. Если строка определена, то каждая запись будет возвращена в виде нового объекта этого класса.
Поведение всех значений определено через PDO и будет извлекать записи как объект stdClass, ассоциативный массив, нумерованный массив или массив нумерованный и ассоциативный соответственно.

  1. PDO::FETCH_OBJ - объект.
  2. PDO::FETCH_ASSOC - ассоциативный массив.
  3. PDO::FETCH_NUM - нумерованный массив.
  4. PDO::FETCH_BOTH - массив с двойным ключом.

Зайдите на http://php.net/manual/en/pdostatement.fetch.php. По умолчанию это PDO::FETCH_OBJ, который можно и использовать, если у вас нет особенных предпочтений.

В этом примере будет выполнен запрос к slave серверу если тот доступен и обработаны записи с результатом выданным в виде ассоциативного массива.

<?php
$result = db_query("SELECT nid, title FROM {node}", array(), array(
  'target' => 'slave',
  'fetch' => PDO::FETCH_ASSOC,
));
?>