Работа с базой данной Drupal. Получение результатов выборки.

В Drupal 7 очень удобно сделано получение результатов выборки из базы данных. В этой статье я приведу примеры функций, позволяющих получить результат в удобном виде.

Для воспроизведения этих примеров, я установил на своей локальной машине "чистый" Drupal 7, добавил 5 нод типа "Article" и написал свой модуль, в котором мы и будем получать из базы эти самые ноды.

Запрос к БД будет предельно простым - получение всех нод из базы:

$nodes = db_select('node', 'n')
->fields('n', array('nid', 'title'))
->execute();

Вывод результатов выборки я буду осуществлять с помощью php функции var_dump().

Получение нескольких записей из БД

fetchAll()

Этот метод преобразует результат выборки в ассоциативный массив объектов, где полями объекта являются выбранные поля. Например запрос:

$nodes = db_select('node', 'n')
->fields('n', array('nid', 'title'))
->execute()
->fetchAll();

вернёт нам следующий результат:

fetchAll-drupal7.png

fetchAllAssoc(key)

Метод fetchAllAssoc(key) позволяет, аналогично методу fetchAll(), получить выборку в виде ассоциативного массива объектов, но ключами этого массива мы можем управлять с помощью переменной key.

Например, следующий запрос вернёт ассоциативный массив со всеми нодами, где ключами массива являются nid соотвествующих нод:

$nodes = db_select('node', 'n')
->fields('n', array('nid', 'title'))
->execute()
->fetchAllAssoc('nid');

Результат:

fetchAllAssoc-drupal7.png

fetchAllKeyed()

Достаточно интересный метод, позволяет получить только 2 поля в виде ассоциативного массива. Т.е. если в предыдущих запросах мы могли получить массив сразу всех полей нод (например nid, title, status), то этот метод позволяет получить только 2 поля, например nid и title нод:

$nodes = db_selectе'node', 'n')
->fields('n', array('nid', 'title', 'status')) // для примера выбираем еще поле status
->execute()
->fetchAllKeyed(); // поля status в результате выборки не будет

В запросе выше я специально добавил еще поле status в результат, чтобы можно было понять работу метода fetchAllKeyed():

fetchAllKeyed-drupal7.png

Как видите, метод fetchAllKeyed() вернул ассоциативный массив, в котором ключами являются nid нод, а значениями title нод. Третьего поля status нет, хотя оно и присутствует в выборке, потому что метод работает только с первыми двумя полями (в нашем случае nid и title ).

fetchAllKeyed(field1,field2)

Есть еще один вариант применения метода fetchAllKeyed(field1, field2), передавая ему аргументы. Переменные field1 и field2 определяют поля, которые будут участвовать в построении ассоциативного массива. Т.е. если в предыдущем случае, вызвав метод fetchAllKeyed() без передачи аргументов, мы получали ассоциативный массив, где участвовали только 2 первых поля в выборке. Теперь, с указанием конкретных полей мы можем указывать, что поле filed1 будет ключами ассоциативного массива, в поле field2 - значениями.

Например следующий запрос вернёт ассоциативный массив всех нод, где ключами являются nid нод, а значениями - время создания этих нод:

$nodes = db_select('node', 'n')
->fields('n', array('nid', 'title', 'status', 'created'))
->execute()
->fetchAllKeyed(0,3); // вернёт nid => created
//  ->fetchAllKeyed(1,2); // вернёт title => status

Результат:

fetchAllKeyed()-drupal7.png

fetchCol(field)

Метод fetchCol позволяет получить результат выборки в виде ассоциативного массива, где значениями являются указанный в field порядковый номер поля выборки. Если field не указан, то по умолчанию будут выведены результаты первого поля. Например:

$nodes = db_select('node', 'n')
->fields('n', array('nid', 'title'))
->execute()
->fetchCol();

Результат выборки:

fetchCol-drupal7.png

Т.е. мы получили массив всех nid нод в БД, т.к. в выборке первым полем является nid ->fields('n', array('nid', 'title')), а поле title не участвует в результате.

А запрос с указанием выводимого поля вернёт следующий результат:

$nodes = db_select('node', 'n')
->fields('n', array('nid', 'title'))
->execute()
->fetchCol(1);

fetchCol-drupal7.png

rowCount()

Метод rowCount() будет полезен, если необходимо получить количество записей в выборке (не в таблице, а именно в выборке). Например, получим количество всех опубликованных материалов:

fetchCol()-drupal7.png

Получение одной записи из БД

fetchAssoc()

Метод fetchAssoc() позволяет получать результат выборки в виде ассоциативного массива, где ключами являются поля выбираемой записи, а значениями - значения этой записи. Например:

$nodes = db_select('node', 'n')
->fields('n', array('nid', 'title'))
->execute()
->fetchAssoc();

Результат выполнения запроса:

fetchAllAssoc-drupal7.png

fetchObject()

Метод fetchObject() аналогичен методу fetchAssoc(), только вместо ассоциативного массива он получает объект:

$nodes = db_select('node', 'n')
->fields('n', array('nid', 'title', 'status', 'created'))
->condition('n.nid', 2)
->execute()
->fetchObject();

Результат выборки:

fetchObject.png

fetchColumn(key)

Метод fetchColumn(key) получает значение указанного (если key не указан, то первого) поля записи в выборке.

Пример:

$nodes = db_select('node', 'n')
->fields('n', array('nid', 'title', 'status', 'created'))
->condition('n.nid', 2)
->execute()
->fetchColumn();

Запрос вернёт значение nid ноды с nid = 2. Конечно, запрос получился не удачным, потому что никому в голову не придёт получать nid ноды по её же nid, он годится только для наглядности.

Теперь изменим немного запрос и укажет индекс поля, которое нужно вывести, например заголовок ноды с nid = 2:

$nodes = db_select('node', 'n')
->fields('n', array('nid', 'title', 'status', 'created'))
->condition('n.nid', 2)
->execute()
->fetchColumn(1);

Этот запрос куда более полезен. Довольно часто нужно получить заголовок ноды, зная её id.

Результат выборки:

fetchColumn.png

Конечно, лучше получать поля ноды с помощью функции node_load(nid) в API Друпала. Но проблема загрузки всей ноды по id заключается в том, что функция грузит все поля ноды, что плохо сказывается на производительности. Так что если необходимо быстро получить какое нибудь поле ноды, лучше воспользоваться прямым запросом к БД.