В 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();
вернёт нам следующий результат:
fetchAllAssoc(key)
Метод fetchAllAssoc(key)
позволяет, аналогично методу fetchAll()
, получить выборку в виде ассоциативного массива объектов, но ключами этого массива мы можем управлять с помощью переменной key
.
Например, следующий запрос вернёт ассоциативный массив со всеми нодами, где ключами массива являются nid
соотвествующих нод:
$nodes = db_select('node', 'n')
->fields('n', array('nid', 'title'))
->execute()
->fetchAllAssoc('nid');
Результат:
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()
вернул ассоциативный массив, в котором ключами являются 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
Результат:
fetchCol(field)
Метод fetchCol
позволяет получить результат выборки в виде ассоциативного массива, где значениями являются указанный в field
порядковый номер поля выборки. Если field
не указан, то по умолчанию будут выведены результаты первого поля. Например:
$nodes = db_select('node', 'n')
->fields('n', array('nid', 'title'))
->execute()
->fetchCol();
Результат выборки:
Т.е. мы получили массив всех nid нод в БД, т.к. в выборке первым полем является nid ->fields('n', array('nid', 'title'))
, а поле title
не участвует в результате.
А запрос с указанием выводимого поля вернёт следующий результат:
$nodes = db_select('node', 'n')
->fields('n', array('nid', 'title'))
->execute()
->fetchCol(1);
rowCount()
Метод rowCount()
будет полезен, если необходимо получить количество записей в выборке (не в таблице, а именно в выборке). Например, получим количество всех опубликованных материалов:
Получение одной записи из БД
fetchAssoc()
Метод fetchAssoc()
позволяет получать результат выборки в виде ассоциативного массива, где ключами являются поля выбираемой записи, а значениями - значения этой записи. Например:
$nodes = db_select('node', 'n')
->fields('n', array('nid', 'title'))
->execute()
->fetchAssoc();
Результат выполнения запроса:
fetchObject()
Метод fetchObject()
аналогичен методу fetchAssoc()
, только вместо ассоциативного массива он получает объект:
$nodes = db_select('node', 'n')
->fields('n', array('nid', 'title', 'status', 'created'))
->condition('n.nid', 2)
->execute()
->fetchObject();
Результат выборки:
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.
Результат выборки:
Конечно, лучше получать поля ноды с помощью функции
node_load(nid)
в API Друпала. Но проблема загрузки всей ноды по id заключается в том, что функция грузит все поля ноды, что плохо сказывается на производительности. Так что если необходимо быстро получить какое нибудь поле ноды, лучше воспользоваться прямым запросом к БД.