Работа с базой данной Drupal. Получение результатов выборки.
В Drupal 7 очень удобно сделано получение результатов выборки из базы данных. В этой статье я приведу примеры функций, позволяющих получить результат в удобном виде.
Для воспроизведения этих примеров, я установил на своей локальной машине "чистый" Drupal 7, добавил 5 нод типа "Article" и написал свой модуль, в котором мы и будем получать из базы эти самые ноды.
Запрос к БД будет предельно простым - получение всех нод из базы:
123
$nodes = db_select('node', 'n')
->fields('n', array('nid', 'title'))
->execute();
Вывод результатов выборки я буду осуществлять с помощью php функции var_dump().
fetchAll()
Этот метод преобразует результат выборки в ассоциативный массив объектов, где полями объекта являются выбранные поля. Например запрос:
1234
$nodes = db_select('node', 'n')
->fields('n', array('nid', 'title'))
->execute()
->fetchAll();
вернёт нам следующий результат:
++++
fetchAll-drupal7.pngfetchAllAssoc(key)
Метод fetchAllAssoc(key) позволяет, аналогично методу fetchAll(), получить выборку в виде ассоциативного массива объектов, но ключами этого массива мы можем управлять с помощью переменной key.
Например, следующий запрос вернёт ассоциативный массив со всеми нодами, где ключами массива являются nid соотвествующих нод:
1234
$nodes = db_select('node', 'n')
->fields('n', array('nid', 'title'))
->execute()
->fetchAllAssoc('nid');
Результат:
++++
fetchAllAssoc-drupal7.pngfetchAllKeyed()
Достаточно интересный метод, позволяет получить только 2 поля в виде ассоциативного массива. Т.е. если в предыдущих запросах мы могли получить массив сразу всех полей нод (например nid, title, status), то этот метод позволяет получить только 2 поля, например nid и title нод:
1234
$nodes = db_selectе'node', 'n')
->fields('n', array('nid', 'title', 'status'))
->execute()
->fetchAllKeyed();
В запросе выше я специально добавил еще поле status в результат, чтобы можно было понять работу метода fetchAllKeyed():
++++
fetchAllKeyed-drupal7.pngКак видите, метод fetchAllKeyed() вернул ассоциативный массив, в котором ключами являются nid нод, а значениями title нод. Третьего поля status нет, хотя оно и присутствует в выборке, потому что метод работает только с первыми двумя полями (в нашем случае nid и title ).
fetchAllKeyed(field1,field2)
Есть еще один вариант применения метода fetchAllKeyed(field1, field2), передавая ему аргументы. Переменные field1 и field2 определяют поля, которые будут участвовать в построении ассоциативного массива. Т.е. если в предыдущем случае, вызвав метод fetchAllKeyed() без передачи аргументов, мы получали ассоциативный массив, где участвовали только 2 первых поля в выборке. Теперь, с указанием конкретных полей мы можем указывать, что поле filed1 будет ключами ассоциативного массива, в поле field2 - значениями.
Например следующий запрос вернёт ассоциативный массив всех нод, где ключами являются nid нод, а значениями - время создания этих нод:
12345
$nodes = db_select('node', 'n')
->fields('n', array('nid', 'title', 'status', 'created'))
->execute()
->fetchAllKeyed(0,3);
Результат:
++++
fetchAllKeyed()-drupal7.pngfetchCol(field)
Метод fetchCol позволяет получить результат выборки в виде ассоциативного массива, где значениями являются указанный в field порядковый номер поля выборки. Если field не указан, то по умолчанию будут выведены результаты первого поля. Например:
1234
$nodes = db_select('node', 'n')
->fields('n', array('nid', 'title'))
->execute()
->fetchCol();
Результат выборки:
++++
fetchCol-drupal7.pngТ.е. мы получили массив всех nid нод в БД, т.к. в выборке первым полем является nid ->fields('n', array('nid', 'title')), а поле title не участвует в результате.
А запрос с указанием выводимого поля вернёт следующий результат:
1234
$nodes = db_select('node', 'n')
->fields('n', array('nid', 'title'))
->execute()
->fetchCol(1);
++++
fetchCol-drupal7.pngrowCount()
Метод rowCount() будет полезен, если необходимо получить количество записей в выборке (не в таблице, а именно в выборке). Например, получим количество всех опубликованных материалов:
++++
fetchCol()-drupal7.pngfetchAssoc()
Метод fetchAssoc() позволяет получать результат выборки в виде ассоциативного массива, где ключами являются поля выбираемой записи, а значениями - значения этой записи. Например:
1234
$nodes = db_select('node', 'n')
->fields('n', array('nid', 'title'))
->execute()
->fetchAssoc();
Результат выполнения запроса:
++++
fetchAllAssoc-drupal7.pngfetchObject()
Метод fetchObject() аналогичен методу fetchAssoc(), только вместо ассоциативного массива он получает объект:
12345
$nodes = db_select('node', 'n')
->fields('n', array('nid', 'title', 'status', 'created'))
->condition('n.nid', 2)
->execute()
->fetchObject();
Результат выборки:
++++
fetchObject.pngfetchColumn(key)
Метод fetchColumn(key) получает значение указанного (если key не указан, то первого) поля записи в выборке.
Пример:
12345
$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:
12345
$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 заключается в том, что функция грузит все поля ноды, что плохо сказывается на производительности. Так что если необходимо быстро получить какое нибудь поле ноды, лучше воспользоваться прямым запросом к БД.