@VladyaKun1210

Как грамотно реализовать пагинацию через класс?

Требуется создать пагинацию на сайте. Как грамотно можно реализовать пагинацию через класс?

class Paginate extends Connection{
                            public function paginateionSelect($page, $total_page){
                                $sql = "SELECT * FROM `clients`";
                                $result = mysqli_query($this->con, $sql);
                                $total_records = mysqli_num_rows($result);
                                $records_per_page = 5;
                                $total_page = ceil($total_records / $records_per_page);

                                if(!isset($_GET['page'])){
                                    $page = 1;
                                }
                                else{
                                    $page = $_GET['page'];
                                }
                                return $total_page;
                            }
                            
                            public function paginationLimit($result1){
                                $start = ($page - 1) * $records_per_page;
                                $sql1 = "SELECT * FROM `clients` LIMIT $start, $records_per_page";
                                $result1 = mysqli_query($this->con, $sql1);
                                return $result1;
                            }
                        }
                        
                        
                        $pagin = new Paginate();



<?php 
          for($page = 1; $page <= $total_page; $page++){
               ?>
          <li class="page-item"><a lass="page-link" href="clients.php?page=<?php echo $page ?>"><?php echo $page ?></a></li>
 <?php
 }
?>
  • Вопрос задан
  • 215 просмотров
Пригласить эксперта
Ответы на вопрос 2
ThunderCat
@ThunderCat Куратор тега PHP
{PHP, MySql, HTML, JS, CSS} developer
Еще раз: Тут нет никакого ооп, у вас получается какой-то процедурный код, засунутый внутрь класса. Это к ооп не имеет никакого отношения. Не пытайтесь сделать деревянную печку, ничего хорошего не получится.
У вас:
Код реализует (такой себе) пэйджинг для одного конкретного запроса (нахрена такой пейджинг засовывать в класс?)
Код ничего не инкапсулирует, тупо выполняется как функция. По сути если мы уберем class Paginate extends Connection{ то ничего не поменяется.
Внутри методов используются глобальные переменные (GET), что само по себе уже лютый говнокод.
Много слов про солид и прочие вещи из ооп не пишу, в виду полного их отсутствия в коде, да и смысл?

По этому решения для вашего случая в контексте ооп просто нет, так как:
Пэйджинг работает с моделями на основе ОРМ, в пэйджинг в качестве аргумента передается модель, и далее уже пэйджинг работает с моделью, используя ее методы работы с хранилищем, а не просто тупо фигачит запросы. У вас моделей просто нет.
Модели подразумевают конкретный интерфейс, который позволяет работать с пэйджингом адекватно. Ну и моделей нет ))
Точкой взаимодействия между моделью и пэйджингом будет контроллер, про который тут вообще у вас никто не в курсе.
Вывод (view) никогда не пересекается с кодом логики, в него просто передаются готовые данные, после чего они вставляются в нужные точки шаблона.
Ответ написан
gzhegow
@gzhegow
aka "ОбнимиБизнесмена"
Попытка не пытка.

1. Пагинация (постраничная навигация) НЕ НАСЛЕДУЕТ соединение, а ИСПОЛЬЗУЕТ его. наследовать = быть КОПИЕЙ С ИЗМЕНЕНИЯМИ, использовать = требовать в коде (ЗАВИСЕТЬ). В ООП можно писать "extends" (наследовать), а можно пробрасывать через конструктор (зависимости). То что вы сделали - это использование "наследования" для "зависимости", оно к вам завтра вернется, когда что-то захотите ещё сюда всунуть, как будете второе наследование делать?

2. Размышляйте так. Чтобы сделать навигацию вам нужно:
1 - имя таблицы
2 - число страниц
3 - отступ, чтобы переходить на вторую страницу
4 - (необязательно) SELECT COUNT результатов, чтобы показать сколько всего страниц
5 - фильтр, чтобы скрыть ненужные результаты (самый прикол в том, что фильтр универсальный сделать не выйдет, т.к. придется написать SQL заново, он весь про фильтры)
6 - сортировка, чтобы выдать в нужном порядке (бывает несколько-ступенчатая сортировка "сначала-по-подгруппе-потом-по-цене", но её никто никогда не делает, лень правит мир)

Вы здесь крышей упадете писать одну функцию, которая делает это всё.

К человекам здесь пришло понимание, что нужно передавать "недоделанный" запрос из функции в функцию, дописывая в него кусочек. Для удобства запрос оборачивают в объект, которые называют Query.

Если вы пытаетесь сделать на чистом SQL запросы - вам придется очень многое изучить. Поэтому как решение я предлагаю такую последовательность действий:
1 - Изучаете, что такое composer, ставите в ваш проект какой-нибудь пакет (пока любой, например, symfony/var-dumper), добиваетесь что работает функция dd() (этот пакет её содержит, вам не нужно функцию создавать) в вашем коде. На самом деле там один консольный вызов и одна строка в коде, там нет "методики на 40 действий"
2 - ставите пакет illuminate/database
3 - гуглите статью "eloquent without laravel"
4 - создаете модельку под вашу таблицу
5 - на модельке вызываете метод ->paginate(), где его для вас заботливо написали
6 - и только здесь начинаете изучать детали, которые хотели выучить сразу, чтобы сделать не просто пагинацию, а фильтруемую и сортируемую пагинацию (если оно надо). Скорее всего у вас появятся классы FilterBuilder, SorterBuilder, PaginationBuilder и Pagination, в которой будет метод вроде ->paginate($query, $paginationBuilder)
7 - что такое паттерн "строитель" (Builder) читать на https://refactoring.guru

У вас долгий путь впереди. Если вы делаете задачу впервые, возможно, вы ушатаете неделю или полторы.

3. Кое-что о запросах. Пагинация с OFFSET имеет смысл только в очень простых запросах. На практике запросы имеют UNION, JOIN и "subquery", чтобы собирать данные, и кое-где работать не будет. Рекомендуется либо сразу оттолкнуться от (id > ?) вместо OFFSET (а заодно охренеть от того, что "айди больше" + "сортировка" опять не пашут, то есть вам по сути надо сделать "rowNum > ?", но почти все СУБД не дают такого параметра и придется КЕШИРОВАТЬ сделав запрос первый раз тяжелый, а следующий раз выбирать номер результата в кеше), либо делать велосипед с выгрузкой результатов в файл, например, и потом с помощью условного $splFileObject->fseek() выбирать прямым указанием номер первой строки и число результатов после (сложнее, веселая задачка потренироваться, на практике - создает больше гемора, чем пользы)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы