API для работы с БД в Drupal 7. На мой взгляд – это самое лучшее API. Поначалу оно может показаться сложным и непонятным. Для работы с БД вы должны понимать, что такое SQL запросы и уметь их писать. Drupal 7 понимает как обыкновенные SQL запросы(как в Drupal 6), так и построенные с помощью API.
Вы также можете почитать на эту тему статью, описывающую работу с БД в Drupal 7.
Начнем с простого select.
Извлечём nid всех нод с типом page.
//подключаемся к таблице.обязательно даём ей псевдоним $q=db_select('node','n'); //задаем условие выборки $q->condition('n.type','page'); //выбираем нужные нам поля //отрабатываем запрос $res=$q->execute();
Теперь применим к переменной res метод fetchAssoc, который выведет результат запроса в виде ассоциативного массива. Код будет выглядеть вот так.
//подключаемся к таблице.обязательно даём ей псевдоним $q=db_select('node','n'); //задаем условие выборки $q->condition('n.type','page'); //выбираем нужные нам поля //отрабатываем запрос $res=$q->execute(); //выводим результат запроса while($rec=$res->fetchAssoc()){ echo $rec['nic'].'<br />'; }
Как видите – каждый оператор запроса является обращением к определённому свойству объекта запроса. Если в запросе нужно обратиться к нескольким таблицам, то у каждой таблицы будет свой псевдоним. И при обращении к методу fields будет указываться псевдоним таблицы, а вторым аргументом этого метода будет массив с именами полей таблицы.
Давайте напишем более сложный запрос. Приджоиним к запросу таблицу пользователей и выведем автора ноды. Используем метод leftJoin.
//подключаемся к таблице.обязательно даём ей псевдоним $q=db_select('node','n'); //задаем условие выборки $q->condition('n.type','page'); //выбираем нужные нам поля //приджоиним таблицу пользователей $q->leftJoin('users','u','u.uid=n.uid'); //отрабатываем запрос $res=$q->execute(); //выводим результат запроса while($rec=$res->fetchAssoc()){ echo $rec['nic'].' -> '.$rec['name'].'<br />'; }
У метода leftJoin 3 аргумента – имя таблицы, её псевдоним и условие. Обратите внимание, в условии оператора нет слова on.
Также вы заметили, что порядок операторов в запросе не оказывает никакого влияния на работу запроса. То есть если в ваш запрос входят операторы order, group, where, having, несколько join и т.д. – то вам абсолютно не важно в каком порядке их писать. Построитель запросов сам их упорядочит и сформируем запрос с которым обратится к БД. Такая форма написания запроса будет кроссплатформенной. Если у Drupal есть драйвер к БД, например MS SQL – то Drupal сам напишет запрос. Который подойдет к этому типу БД, так как некоторые запросы будут выглядеть по-разному.
Также легко вывести запрос на экран. Для этого следует написать такой код.
echo (string)$q;
Такая конструкция выведет следующее.
SELECT n.nid AS nid, u.name AS name FROM {node} n LEFT OUTER JOIN {users} u ON u.uid=n.uid WHERE (n.type = :db_condition_placeholder_0)
Как видите, названия таблиц уже обернуты в кавычки, и такой запрос будет работать с таблицами с префиксами.
Опираясь на такое API можно написать фактически любой запрос. Давайте сделаем апдейт таблицы.
$q=db_update('node'); $q->condition('type','page'); $q->execute();
Такой запрос проапдейдит таблицу node, установив значение поля type равным type-1 и установит автором пользователя с uid равным 10. Данный запрос сработает для строк с полем type равным page.
Для удаления строк можно использовать оператор db_delete. Для вставки строк db_insert.
А теперь составим сложный запрос. В нём почти 20 строк. Составить такой запрос несложно и очень удобно понять, как сработает данный запрос, просто посмотрев на код.
// соединение с бд,подключение пагинации $q=db_select('custom_sessionss','s')->extend('PagerDefault'); //джоиним таблицы $q->leftjoin('custom_videos', 'v', 's.videoid = v.id'); $q->leftjoin('custom_guid','ng','ng.guid=v.avsurl'); $q->leftjoin('node', 'n', 'n.nid = ng.nid'); //условия $q->condition('s.playerid',$player_list,'='); $q->condition('s.datetimestart',$day_first_int,'>'); $q->condition('s.datetimestart',$day_end_int,'<'); $q->condition('n.title','','<>'); //извлекаемые поля $q->addExpression('count(*)','views'); $q->addExpression('count(distinct s.userid)','uniques'); //группировки $q->groupBy('s.videoid'); $q->groupBy('v.avsurl'); $q->groupBy('n.title'); //сортировки $q->orderBy('views','desc'); $q->orderBy('uniques','desc'); //выполнение запроса $res=$q->limit(20)->execute(); </');>
В этом запросе есть условия больше, меньше, равно и не равно. Если оператор условия не стоит-то по умолчанию он будет считаться как знак равенства. Также посчитано количество строк оператором count. Есть группировки и сортировки.
В этом запросе группировки и сортировки можно было бы уместить в двух(вместо текущих 5) вызовах методов groupBy и orderBy, но такой запрос сработал бы только в MySQL. Данная форма более кроссплатформенна и сработает и в других типах БД.