Как комфортно работать с большими таблицами в CRM: Datatables Server-Side

В CRM/ERP-системах, которые мы разрабатываем под заказ, всегда используется чудесный компонент DataTables. Очень удобный процессор табличных данных, поиск, фильтр, гибкость — это всё про него. Мы его любим.

Базовое использование данного плагина подразумевает обработку имеющейся таблицы <table> или подгрузку JSON-массива. Проблемы начинаются, когда таблица имеет большое количество строк, а наши CRM-системы очень часто содержат таблицы данных от 1000 строк и выше.

В этих случаях разработчики DataTables рекомендуют использовать серверную обработку выходных данных (т.н. Server-side Processing), которая предусматривает проведение операций выборки, фильтра и сортировки на стороне сервера, и возвращает на страницу уже сформированный контент удобными порциями. В результате всё работает шустро, браузер не виснет. Подробное описание данного приёма, с примерами реализации и массой других фишек, находится здесь.

Приведённый выше пример ссылается на созданный разработчиками  DataTables PHP-класс ssp.class.php (найти его можно здесь). Если внимательно посмотреть на примеры его использования, можно понять, что он не подойдёт для минимально сложных SQL-выборок из базы данных. Вы не сможете, например, использовать JOIN — и как теперь выбирать необходимые данные? Ещё одним недостатком данного класса, по крайней мере для нас, является то, что он самостоятельно подключается к БД — мы же работаем через другой класс.

Для того, чтобы комфортно работать с большими таблицами, мы будем руками писать собственные модификаторы запросов.  Рассмотрим пример крупной клиентской базы в CRM: вытягиваем информацию о всех «активных» клиентах, их название и УНП, а также данные договора с ними. Разумеется, это простой пример.

По этой ссылке вы найдёте, как включить серверную обработку на стороне HTML/JS, а вот PHP-код придётся писать самим. Здесь под заголовком Sent parameters вы найдёте полный список тех данных запроса, которые DataTables посылает в ваш PHP-скрипт в $_REQUEST. Следовательно:

Разумеется, входные данные необходимо обрабатывать на предмет зловредного контента, тут вы и сами справитесь.

Мы уже видим определённые знакомые вещи, которые будут использоваться как LIMIT, OFFSET, ORDER… А для того, чтобы обработать строку поиска, напишем такую функцию (она пригодится в дальнейшем):

Эта функция, как мы видим, принимает массив наших столбцов, и если для него установлено значение searchable: true — добавляет его в строку SQL-запроса. Я также добавил сюда параметр extra_columns на тот случай, если поиск нужен по какому-нибудь иному полю, которое не имеет отдельного столбца. Обратите внимание, что выходная строка предполагает наличие хотя бы одного условия в вашем WHERE — в противном случае её потребуется немного изменить.

Используем функцию для включения в поиск ещё и поля УНП:

И вот как теперь выглядит наша строка SQL-запроса:

Предельно просто, не правда ли?

Теперь мы должны передать в DataTables значения recordsTotal (сколько всего строк в базе данных)  и recordsFiltered (сколько строк мы возвращаем). Эти данные нужны для формирования пагинации и строки «Показываем с 1 по 10 из 57 записей». Мы не можем подсчитать количество возвращённых предыдущим запросом строк, потому что используется LIMIT — поэтому нам придётся сделать ещё два SQL-запроса (или один, если $search_clause пустой):

Теперь формируем выходные данные, тут всё просто:


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



Игорь Балькин
Автор: Игорь Балькин. Веб-разработчик с 2001 года. Разработчик сайтов на WordPress, CRM и веб-приложений. Минск, Беларусь. Контактная информация.

Прокомментировать

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать HTML-тэги и атрибуты:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>