Публикация в группе: Плагин WP-Recall - Личный кабинет на WordPress

Категории группы: Полезное

Добавлено в закладки: 3

Если вам, как разработчику, приходилось создавать в базе данных свою таблицу для хранения данных, то вы знаете, как важно написание своего функционала для работы с этой таблицей. Обязательно требуется написать функции для:

  • добавление данных,
  • их обновление или изменение,
  • удаление,
  • а также их получение.

Из всего этого списка, именно получение данных из таблицы может вызвать наибольшие проблемы у разработчика, потому что данные можно получать по множеству критериев и важно получить удобный инструмент для получения данных по этим критериям не только для себя, но и предложить его другим разработчикам, которые будут работать с вашей таблицей. Чем больше таблица имеет столбцов, тем больше комбинаций входящих параметров на выборку данных она может принимать, но не у всех хватает времени и возможностей, чтобы учесть все эти параметры при написании функции на выборку. Как правило, ограничиваются выборкой, как им кажется, наиболее важных данных, игнорируя другие, а параметры выборки могут быть жестко ограничены, что снижает возможности для работы с данными таблицы.

Опыт написания плагинов или дополнений привел меня к необходимости писать под каждую новую таблицу в базе данных свой класс, который позволял бы строить сложные запросы для получения данных. На основе таких классов было очень удобно создавать шорткоды, которые бы выводили определенные данные в зависимости от полученных атрибутов, но еще удобнее было взаимодействовать с классом через php-код, формируя массив определенных параметров и сразу получая нужные данные, без необходимости работы напрямую с классом $wpdb.

Со временем подобных классов стало достаточно много (один для каждой таблицы) и так как суть у них была одна, то решено было написать универсальное решение, которое позволить работать со всеми кастомными таблицами плагина и дополнений из одного места.

Шестнадцатая версия плагина WP-Recall, кроме всего прочего, получила в ядро новый класс Rcl_Query, который позволил перевести почти все запросы к БД на получение данных  на себя, сформировав, таким образом, рекомендуемый стандарт, которым очень удобно пользоваться. Рассмотрим подробнее порядок работы с новым классом и прикинем его возможности для применения в наших будущих разработках к плагину WP-Recall.

Внимание! Для того, чтобы читать и понимать суть написанного ниже, вы должны иметь представление о работе с классом wpdb и уметь строить SQL-запросы к базе данных.

Для начала рассмотрим базовый пример работы с данным классом напрямую, а затем перейдем к более удобному варианту.

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

Чтобы начать получать данные из этой таблицы через класс Rcl_Query необходимо сообщить классу структуру этой таблицы. Делается это следующим образом:

Как видно из кода выше, мы сформировали массив с данными таблицы, указали ее имя, псевдоним и перечислили наименование всех столбцов с которыми будем в дальнейшем работать и передали этот массив в класс Rcl_Query. В результате мы получили объект $query, который и позволит нам получать данные из нашей таблицы согласно переданных параметров.

Мы помним, что для построения запросов к БД через класс $wpdb мы могли использовать методы: get_var, get_row, get_col и get_results. При работе с классом Rcl_Query эти методы также можно и нужно использовать, только передавать в них мы будем не строку запроса, а массив.

Итак давайте рассмотрим несколько простых примеров.

... WHERE 'a' = 'b' ...

Для построения несложных запросов в которых нужно получить данные по значению определенного столбца строим массив в котором указываем наименование столбца и указываем нужное значение для него:

1. Получим данные группы с идентификатором 10:

В качестве результата мы получим объект с данными группы идентификатор, которой равен 76. Причем будут выбраны данные всех столбцов найденной строки, примерно со следующей структурой:

Для указания условий выборки можно использовать наименования всех зарегистрированных столбцов таблицы, например:

SELECT 'a', 'b' ...

Если необходимо выбрать значения только из определенных столбцов таблицы, то используем их перечисление внутри массива 'fields'.

2. Для того, чтобы получить только значения admin_id и group_status, построим следующий запрос:

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

3. Если мы хотим получить значение только одного столбца, то имеет смысл использовать метод get_var:

тогда мы получим только идентификатор администратора группы, в данном случае, "1".

Перейдем к более сложным и интересным запросам с методом get_results.

... WHERE 'a' = 'b'  AND 'c' = 'd' ...

4. Получим данные групп, в которых admin_id равен 1, а group_status - 'closed', т.е. закрытые группы пользователя с ID 1:

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

... WHERE 'a' >= 'b'  AND 'c' <= 'd' ...

5. Чтобы получить данные со значения от указанного или со значениям до указанного включительно, необходимо при указании наименования колонки использовать постфиксы "__from" и "__to". Например, выберем группы в которых количество участников более 100, но менее 200:

... WHERE 'a' LIKE '%b%' ...

5. Для выборки данных через указание паттерна LIKE необходимо указывать постфикс "__like":

... ORDER BY 'a' ORDER ...

Для сортировки по значениям определенного столбца таблицы используем указание параметра 'orderby' указав в качестве значения наименования нужного столбца таблицы.

6. Усложним запрос, получив только значения указанных столбцов и отсортировав по кол-ву пользователей в группе по убыванию:

Результат данного запроса:

... LIMIT a,b ...

Для пропуска определенного количества найденных первых значений из выборки используется параметр 'offset' с указанным значением количества пропускаемых строк. Параметр 'number' указывает максимальное количество найденных строк в выборке.

7. Дополним запрос, указав к выборке только 3 группы, пропустив первые 5:

если для параметра number указать значение "-1", то будут выбраны все записи без ограничений

... 'a' IN (b,c) ...

Если необходимо выбрать строки с определенными значениями указанных столбцов, то используется указание параметра с именем построенным по шаблону: 'colname__in', а в качестве значения указывается массив значений столбца к выборке. Например:

8. Получим все группы, в которых администраторами являются пользователи с ID равным 1 и 44, отсортируем результат по идентификатору группы:

... 'a' NOT IN (b,c) ...

Для исключения из выборки найденных строк по определенным параметрам используется указанием параметра, имя которого строится на основании имени столбца по шаблону: 'colname__not_in', а в качестве значения указывается массив со нужными значениями.

9. Получим 10 групп, пропустив первые 5 и исключив из выборки группы с идентификаторами 1, 5 и 23:

SELECT COUNT('a') ...

10. Посчитаем все открытые группы сайта:

В метод 'count', можно передать любой массив из примеров выше и результатом будет подсчет количества данных выборки, согласно переданных параметров.

DATE_QUERY

11. Выберем все открытые группы, созданные 20 апреля 2016 года:

12. Выберем все группы, созданные за январь и февраль 2017 года:

13. Выберем группы, созданные с 10 января 2017 года по 25 января 2017 года:

Регистрация дочернего класса для таблицы

Примеры выше показывают основы работы с классом Rcl_Query напрямую, но на практике подобный подход не удобен, тк придется постоянно формировать массив с данными таблицы и передавать его в класс.

Для того, чтобы упростить процесс работы со своей таблицей имеет смысл зарегистрировать дочерний класс, который и будет задавать данные нужной таблицы:

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

Оборачиваем дочерний класс в функцию

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

В результате мы получим удобную функцию, которая сможет принимать массив всех параметров, что мы рассматривали выше и будет отдавать данные согласно переданных параметров. Останется только задокументировать ее и предложить для работы другим разработчикам. Пример работы:

Мы рассмотрели порядок работы с классом Rcl_Query на примере одной таблицы. Подобным образом, буквально за минуту, можно подключать к классу любую свою таблицу и сразу после этого начинать легко строить запросы и получать нужные данные.

JOIN. Работа с несколькими таблицами

Для того, чтобы удобно работать с несколькими таблицами, то лучше всего  зарегистрировать для данных таблиц дочерние классы с данными этих таблиц, чтобы затем быстро подставлять их в массив запроса, но, если такой необходимости или возможности нет, то можно передавать данные таблиц прямо в массив. Мы рассмотрим вариант работы с двумя заранее зарегистрированными query-классами двух таблиц.

Чтобы сформировать запрос ко второй таблице, необходимо дополнить массив запроса массивом 'join_query', где будут размещаться данные запроса ко второй таблице. Данный массив должен содержать некоторые обязательные элементы:

'table' - массив с данными таблицы, со структурой, которую мы рассматривали выше при регистрации первой таблицы,

'on_*' - параметр запроса ON, дополняется наименованием колонки из первой таблицы, а значением является имя колонки из второй таблицы, например, запись вида: 'on_ID' => 'user_id' для таблиц wp_users и wp_usermeta, будет интерпретироваться как 'ON wp_users.ID=wp_usermeta.user_id',

'join' - может быть LEFT, RIGHT, INNER и тд., по-умолчанию - INNER.

Вторая таблица будет иметь следующую структуру:

Допустим мы уже зарегистрировали для этой таблицы свой query-класс Rcl_Groups_Users_Query, поэтому можем переходить к построению запроса. Дополним пример №4 запросом ко второй таблице и получим данные пользователей выбранных из первой таблицы групп:

Переданный массив сформирует следующий запрос:

Для уточнения запроса, мы также можем дополнять массив 'join_query' параметрами, которые рассматривались в примерах выше. Например, дополним запрос указав для выборки группы куда входит пользователь с ID 44, а выбирать из первой и второй таблицы будем только поля указанные в параметрах 'fields':

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

Таким образом, мы можем легко работать с двумя, тремя и большим количеством таблиц.

Конечно, в первую очередь, класс Rcl_Query стоит рассматривать как решение для быстрого построения несложных запросов, но как показывает практика именно такие и составляют 90% от всех запросов, которые приходится писать под очередной плагин или дополнение. Класс будет постепенно развиваться, дополняться новыми возможностями, что будет автоматически расширять возможности для выборки данных для всех таблиц подключенных к классу, что очень удобно.

Некоторые разработчики могут усомниться в необходимости данного класса, дескать, нам и с wpdb неплохо живется. Спорить не буду, инструменты должны использоваться с учетом своей целесообразности, если кому то проще быстро написать простой запрос через wpdb, то это вполне оправдано, но когда речь идет о построении гибкого функционала и возникает необходимость получения данных на основе непостоянного множества параметров, то класс Rcl_Query будет просто незаменим.

Только лишь создав таблицу в базе данных и подключив ее к классу Rcl_Query разработчик сразу получает возможность работать с данными этой таблицы и получать данные по множеству входящих параметров!

Класс Rcl_Query - гибкий и удобный, а самое главное, несложный инструмент для работы, сохраняющий время разработчика. Буду рад, если он кого то заинтересует и будет применяться в вашей работе.

3

Автор публикации

не в сети 6 часов

Андрей CS

10k

пока занят

Комментарии: 1780Публикации: 411Регистрация: 30-11--0001Продаж/Покупок: 16725/114