Завантаження публікації
ОГОЛОШЕННЯ

Пагінація та фільтри в Laravel: як робити списки з query string без хаосу

Покроково пояснюємо, як будуються адмінські списки: пагінація, пошук, фільтри по даті/статусу/автору, збереження параметрів у URL і правильна робота “назад/вперед” без втрати умов.


Максим Третяк
Максим Третяк
Газета Дейком | 30.12.2025, 15:00 GMT+3; 08:00 GMT-4

У будь-якій адмінці і в більшості публічних розділів є списки: новини, теми, клієнти, рахунки, логи, медіа. Якщо список без пагінації — він швидко стає повільним і незручним. Якщо фільтри зроблені “на кнопках” без URL-параметрів — користувач не може поділитися посиланням, не може повернутися назад і втрачає контекст. Тому стандарт у Laravel простий: списки мають бути з пагінацією, а фільтри — через query string у URL.

Пагінація означає, що ти показуєш дані частинами: 20–50 записів на сторінку, а решту — на наступних сторінках. Це зменшує навантаження на базу, прискорює рендер і робить інтерфейс стабільним. У Laravel пагінація робиться на рівні запиту: ти не витягуєш “все”, а просиш базу одразу віддати сторінку.

Ключове правило: пагінація завжди має бути “останнім кроком” після всіх фільтрів. Тобто спочатку ти збираєш запит: пошук, статус, дата, автор, сортування. І тільки потім викликаєш paginate(). Якщо зробити навпаки або фільтрувати вже колекцію в PHP, ти або отримаєш неправильні результати, або вб’єш продуктивність.

Фільтри через query string — це коли параметри йдуть у URL, наприклад ?search=laravel&status=published&from=2025-01-01&page=2. Перевага така: URL стає “станом” сторінки. Ти можеш скопіювати посилання і відкрити рівно той самий список. Кнопки “назад/вперед” у браузері працюють логічно. І пагінація не губить умови, якщо ти правильно їх прокинув.

Як правильно будувати фільтри. Ти визначаєш набір дозволених параметрів: наприклад search, status, user_id, from, to, section, resource, sort. Далі береш їх з request, і для кожного параметра додаєш умову до query лише якщо параметр реально переданий. Це важливо: фільтр не має ламати запит, якщо користувач нічого не обрав.

Пошук search зазвичай робиться через LIKE по заголовку або опису. Тут треба бути дисциплінованим: пошук по великих текстових полях без індексів може бути дорогим. На старті це нормально, але в реальному продукті з часом або додають повнотекстовий пошук, або обмежують поля, або будують окремі рішення. Для навчання достатньо розуміти: пошук = додаткове навантаження, і його треба контролювати.

Фільтр по статусу — класика. Він повинен працювати через точне значення, а не через “якось”. Тобто status має бути обмежений списком дозволених станів, інакше ти отримаєш дивні запити і проблеми з безпекою в логіці. Важливо, щоб у базі був індекс по статусу, якщо це поле активно використовується у списках.

Фільтр по даті — ще одна типова річ, і тут головне не заплутатися, що саме фільтруємо: created_at чи published_at. У медіа-проєктах часто критично саме published_at, бо створили новину вчора, але опублікували сьогодні. Тому фільтр має явно пояснювати, по якій даті він працює, і мати правильні межі “від/до”.

Діапазон дат будується як дві умови: від певного дня і до певного дня. Важливо правильно включати “до кінця дня”, якщо ти фільтруєш по даті без часу. Інакше користувач вибирає “до 30 числа”, а записи 30-го після 00:00 можуть “зникати”. На практиці це вирішується нормалізацією меж: початок дня для from і кінець дня для to.

Фільтр по автору або користувачу (user_id) — ще один стандарт. Тут важливо не тягнути список користувачів “вічно”: ти або робиш пошук/селект, або даєш обмежений список. На рівні SQL це простий WHERE по user_id, але для продуктивності потрібен індекс. Для UI важливо, щоб після вибору автора параметр залишався в URL і не губився при переході по сторінках.

Сортування теж треба робити через query string, бо це частина стану списку. Наприклад sort=published_at і dir=desc. Мінімальний стандарт: дозволити сортування по 1–3 полях і жорстко обмежити список дозволених значень, щоб не підставляли довільні колонки. Це не лише про порядок, а й про безпеку та стабільність.

Переходимо до головної практичної проблеми: як зробити так, щоб пагінація не скидала фільтри. Якщо ти просто робиш paginate(50) і виводиш посилання, Laravel згенерує сторінки ?page=2, але без твоїх параметрів. Тому стандарт — “пришити” поточні параметри до пагінації. У Laravel це робиться через withQueryString() або через ручне appends().

Важливо зрозуміти логіку: URL параметри мають зберігатися на кожному кліку “наступна сторінка”. Якщо користувач відфільтрував список, він очікує, що сторінка 2 буде тим самим фільтром, а не “все підряд”. Тому withQueryString() — це не дрібниця, а обов’язковий стандарт для нормальних списків.

На рівні інтерфейсу фільтри мають бути формою з методом GET. Це простий і правильний підхід: користувач обирає параметри, натискає “Фільтрувати”, і сторінка відкривається з query string. GET важливий саме тим, що параметри видно в URL. Після цього ти у формі підставляєш поточні значення з request, щоб елементи не скидалися при перезавантаженні.

Для полів форми тут працює той самий принцип, що і для old(), але простіше: ти береш значення прямо з request('search'), request('status') тощо. Тобто фільтр “пам’ятає”, що було обрано, бо це в URL. Це робить сторінку предиктивною: користувач бачить, які умови активні.

Є ще одна деталь, яка економить нерви: коли користувач змінює фільтри, треба скидати сторінку на першу. Інакше він був на page=5, застосував новий фільтр і отримав порожньо, бо під фільтром існує лише 1–2 сторінки. Тому в UI або не передавай page при сабміті фільтра, або явно очищай його. Це дрібна річ, але вона зменшує “чому нічого не показує”.

З точки зору продуктивності головне правило таке: фільтри мають підтримуватися індексами. Якщо ти фільтруєш по published_at, status, user_id, то ці поля повинні бути індексовані, інакше на великій таблиці список стане повільним. Пагінація зменшує обсяг результату, але не прибирає проблему пошуку — база все одно має знайти потрібні рядки, і індекс тут вирішує.

Висновок: пагінація і query string-фільтри — це стандарт, який робить списки зручними і керованими. Правильний порядок завжди один: взяли параметри з URL, додали умови до query, застосували сортування, зробили paginate і обов’язково зберегли query string у посиланнях пагінації. Якщо ти освоїш цю схему, ти зможеш будувати будь-яку адмінську сторінку з фільтрами без хаосу, і вона не зламається, коли даних стане в рази більше.


Максим Третяк — Кореспондент, який спеціалізується на суспільно важливих темах, пише про політику, фінансові ринки та економіку. Він проживає та працює в Україні.

Цей матеріал є частиною розгорнутої теми: Web-програмування, яка охоплює численні цікаві аспекти цієї події. Газета «Дейком» ретельно відстежує події, проводячи перевірку джерел та інформації, щоб забезпечити нашим читачам найбільш точне та актуальне інформування.

Цей матеріал опубліковано 30.12.2025 року о 15:00 GMT+3 Київ; 08:00 GMT-4 Вашингтон, розділ: Освіта, із заголовком: "Пагінація та фільтри в Laravel: як робити списки з query string без хаосу". Якщо в публікації з'являться зміни, про це буде зазначено та описано у кінці публікації.

Читайте щоденну газету та загальну стрічку новин газети Дейком, яка поєднує багато цікавого в понад 40 розділах з усіх куточків світу.


Save
ОГОЛОШЕННЯ

Новини, які можуть Вас зацікавити:

Штатні та позаштатні журналісти газети «Дейком» щодня готують сотні публікацій, щоб читачі отримували найоперативнішу, перевірену й глибоку інформацію. Ми працюємо для тих, хто хоче розуміти суть подій, бачити широку картину та бути на крок попереду.

Останні новини

Вибір редакції