За последние 24 часа нас посетили 22487 программистов и 1012 роботов. Сейчас ищут 659 программистов ...

MVC пагинация

Тема в разделе "PHP для новичков", создана пользователем Miron9900, 9 дек 2019.

Метки:
  1. Miron9900

    Miron9900 Новичок

    С нами с:
    28 фев 2019
    Сообщения:
    11
    Симпатии:
    0
    Не так давно начал изучать ООП и решил попробовать сделать постраничный вывод новостей с использованием mvc, вроде бы все получилось, но возникла одна проблема:
    Есть главная страница http://news.mvc/ здесь отображаются 5 новостей + пагинация внизу 1,2,3,4,5.... При щелчке на нужную страницу перекидывает на пустую страницу http://news.mvc/page=1 , как сделать, чтобы изначальный адрес был http://news.mvc/news/
    или как сделать чтобы в адресную строку добавлялось /news/ при переходе на страницы?Или хотя бы подскажите, где это сделать, а там постараюсь сам решить проблему
    Если открыть http://news.mvc/ и сначала щелкнуть на конкретную новость открывается http://news.mvc/news/id_новости , а потом вернуться на все новости то переход уже будет работать http://news.mvc/news/page-1
    Код (Text):
    1.  
    2. class Pagination
    3. {
    4.    
    5.     private $max = 114;
    6.    
    7.     private $index = 'page';
    8.    
    9.     private $current_page;
    10.    
    11.     private $total;
    12.    
    13.     private $limit;
    14.     // Запуск необходимых данных для навигации
    15.     public function __construct($total, $currentPage, $limit, $index)
    16.     {
    17.         // Устанавливаем общее количество записей
    18.         $this->total = $total;
    19.         // Устанавливаем количество записей на страницу
    20.         $this->limit = $limit;
    21.         // Устанавливаем ключ в url
    22.         $this->index = $index;
    23.         // Устанавливаем количество страниц
    24.         $this->amount = $this->amount();
    25.         // Устанавливаем номер текущей страницы
    26.         $this->setCurrentPage($currentPage);
    27.     }
    28.     // Для вывода ссылок.HTML-код со ссылками навигации
    29.     public function get()
    30.     {
    31.         // Для записи ссылок
    32.         $links = null;
    33.         // Получаем ограничения для цикла
    34.         $limits = $this->limits();
    35.         $html = '<div class="pagination">';
    36.         // Генерируем ссылки
    37.         for ($page = $limits[0]; $page <= $limits[1]; $page++) {
    38.             // Если это текущая страница, ссылки нет и добавляется класс active
    39.             if ($page == $this->current_page) {
    40.                 $links .= '<a href="#" class="selected">' . $page . '</a>';
    41.             } else {
    42.                 // Иначе генерируем ссылку
    43.                 $links .= $this->generateHtml($page);
    44.             }
    45.         }
    46.             $html .= $links . '</div>';
    47.             // Возвращаем html
    48.             return $html;
    49.     }
    50.     //Для генерации HTML-кода ссылки.$page - номер страницы
    51.     private function generateHtml($page, $text = null)
    52.     {
    53.         // Указываем, что текст - цифра страницы
    54.         $text = $page;
    55.         $currentURI = rtrim($_SERVER['REQUEST_URI'], '/') . '/';
    56.         $currentURI = preg_replace('~/page-[0-9]+~', '', $currentURI);
    57.         // Формируем HTML код ссылки и возвращаем
    58.         return
    59.             '<a href="'.$currentURI.  $this->index . $page . '">' . $text . '</a>';
    60.     }
    61.     // Для получения, откуда стартовать
    62.     private function limits()
    63.     {
    64.         // Конец - общее количество страниц
    65.             $end = $this->amount;
    66.         // Начало - минус $this->max от конца
    67.             $start = $this->amount - $this->max > 0 ? $this->amount - $this->max : 1;
    68.         // Возвращаем
    69.         return
    70.             array($start, $end);
    71.     }
    72.     //Для установки текущей страницы
    73.     private function setCurrentPage($currentPage)
    74.     {
    75.         # Получаем номер страницы
    76.         $this->current_page = $currentPage;
    77.         # Если текущая страница больше нуля
    78.         if ($this->current_page > 0) {
    79.             # Если текущая страница меньше общего количества страниц
    80.             if ($this->current_page > $this->amount)
    81.             # Устанавливаем страницу на последнюю
    82.                 $this->current_page = $this->amount;
    83.         } else
    84.         # Устанавливаем страницу на первую
    85.             $this->current_page = 1;
    86.     }
    87.     // Для получения общего числа страниц
    88.     private function amount()
    89.     {
    90.         // Делим и возвращаем
    91.         return ceil($this->total / $this->limit);
    92.     }
    93. }
    94. routes:
    95. return array(
    96.     'news/([0-9]+)' => 'news/view/$1',
    97.     'news' =>'news/index',
    98.     'news/page-([0-9]+)' => 'news/index/$1',
    99.     '' => 'news/index',
    100. );
    101. [code]
    102. Класс Route
    103. [code]
    104. class Router
    105. {
    106.     private $routes; //Маршруты
    107.     public function __construct()
    108.     {
    109.         $routesPath = ROOT . '/config/routes.php';
    110.         $this->routes = include($routesPath);
    111.     }
    112.     //Возвращает строку запроса
    113.     private function  getUri() {
    114.         if(!empty($_SERVER['REQUEST_URI'])) {
    115.            return trim($_SERVER['REQUEST_URI'],'/');
    116.         }
    117.     }
    118.     public function run()
    119.     {
    120.         // Получить строку запроса
    121.     $uri = $this->getUri();
    122.         // Проверить наличие такого запроса в routes.php
    123.     foreach ($this->routes as $uriPattern=>$path){
    124.         // Сравниваем $uriPattern и $uri
    125.        if (preg_match("~^$uriPattern$~",$uri)){
    126.            // Получаем внутренний путь из внешнего согласно правилу.
    127.            $internalRoute = preg_replace("~^$uriPattern~",$path,$uri);
    128.            // Определить контроллер, action, параметры
    129.            $segments = explode('/',$internalRoute);
    130.            $controllerName = array_shift($segments) . 'Controller';
    131.            $controllerName = ucfirst($controllerName);
    132.            $actionName = 'action'.ucfirst(array_shift($segments));
    133.            $parameters = $segments;
    134.            // Подключить файл класса-контроллера
    135.            $controllerFile = ROOT.'/controllers/'. $controllerName.'.php';
    136.            if (file_exists($controllerFile)){
    137.                include_once($controllerFile);
    138.            }
    139.            // Создать объект, вызвать метод (т.е. action)
    140.            $controllerObject = new $controllerName;
    141.            $result = call_user_func_array(array($controllerObject, $actionName),$parameters) ;
    142.            if ($result!=null){
    143.                break;
    144.            }
    145.        }
    146.     }
    147.     }
    148. }
    149. [code]
    150. Заранее благодарю!
    151.  
    152. [B][/B]
     
  2. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.792
    Симпатии:
    650
    Вопрос, откуда вообще взялись дубли / и /news/ (про /page=1 – WTF Пропустили вопросительный знак или написали = вместо черточки? – я уже молчу, как и про /news/page-1).

    У вас должна быть ф-ция представления, которая собирает адреса по каким-то исходным данным, например:
    PHP:
    1. href="<?= pagelink(1,'','news') ?>"
    Это, предположительно, для трехкомпонентных адресов, например /news[/100500][?page=2], при этом параметры ф-ции имеют обратный порядок относительно расположения компонентов в адресе. Использование дефолтных значений параметров, учитывающих адрес текущей страницы, тоже вполне допустимо, например pagelink(1) на странице /news?page=2 и т.п. В этой же ф-ции уместно делать «ротацию», скрывая параметр page при поступлении 0 или 1.
     
    #2 miketomlin, 9 дек 2019
    Последнее редактирование: 9 дек 2019
    Miron9900 нравится это.