Облако ссылок Добавить сайт Опубликовать Пользователи Категории

Сервис полезной информации


Размещайте полезную информацию и одновременно продвигайте свои проекты.


Узнать больше

Как на MVC и PHP сделать вывод новостей из БД с использованием пагинации


X

Как на MVC и PHP сделать вывод новостей из БД с использованием пагинации

В прошлой статье мы рассматривали, как добавить новости в базу данных. Теперь мы будем выводить эти новости постранично с использование класса Pagination.

Для начала прописываем путь к обработчику страницы.

'news' => 'news/newsPage',

 

Теперь создадим сам обработчик в файле NewsController.php. Он по умолчанию получает значение page равное 1, это нужно для того, чтобы пагинация начиналась с первой страницы.

В NewsList  с помощью функции getNewsLimit получаем сами новости из таблицы базы данных. В total при помощи функции getCountNews запишется общее количество новостей.

Затем создаем Pagination, он имеет следующий синтаксис: Pagination(общее количество новостей, номер страницы, максимальное количество новостей на странице, ‘символ который будет подставлен в адресную строку перед номером страницы’)

В итоге у нас получится вот такой метод:

public function actionNewsPage($page = 1)
{
    $NewsList = News::getNewsLimit($page);
    $total = News::getCountNews();
    $pagination = new Pagination($total, $page, News::SHOW_BY_DEFAULT, '');
    require_once(ROOT . '/views/site/news.php');
    return true;
}

 

Теперь опишем используемые функции и константу:

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

const SHOW_BY_DEFAULT = 3;

 

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

Допустим, мы переходим на третью страницу пагинации, значение переменной page становится равным трем, так как отчет записей с базы данных мы начинаем с нуля. Максимальное количество элементов на странице равно трем.  Мы отнимаем от page единицу и умножаем на максимальное количество новостей. Таким образом, мы получаем выражение (3-1)*3, оно равно числу шесть, то есть мы будем брать записи, из БД начиная с шестой по счету.

В переменную limit мы записываем максимальное количество записей на странице. Переменная limit будет указывать, сколько записей мы вытянем из базы данных.

В результате выполнения SQL запроса мы получим limit записей, начиная от offset элемента.

public static function getNewsLimit($page=1){
    $limit = self::SHOW_BY_DEFAULT;
    $offset = ($page - 1) * self::SHOW_BY_DEFAULT;
    $db = Db::getConnection();
    $sql = 'SELECT * FROM news ORDER BY id DESC LIMIT :limit OFFSET :offset ';
    $result = $db->prepare($sql);
    $result->bindParam(':limit', $limit, PDO::PARAM_INT);
    $result->bindParam(':offset', $offset, PDO::PARAM_INT);
    $result->execute();
    $i = 0;
    $news = array();
    while ($row = $result->fetch()) {
        $news[$i]['id'] = $row['id'];
        $news[$i]['title'] = $row['title'];
        $news[$i]['date'] = $row['date'];
        $news[$i]['img_url'] = $row['img_url'];
        $news[$i]['url'] = $row['url'];
        $i++;
    }
    return $news;
}

 

Функция getCountNews. Простой SQL запрос, который считает количество элементов в таблице базы данных по id:

public static function getCountNews()
{
    $db = Db::getConnection();
    $sql = 'SELECT count(id) AS count FROM news';
    $result = $db->prepare($sql);
    $result->execute();
    $row = $result->fetch();
    return $row['count'];
}

 

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

С помощью цикла foreach выводим записи на страницу. Массив NewsList мы получаем из обработчика который находится в NewsController. Эта страница имеет следующий листинг:

<html>
<head>
    <title>Новости</title>
</head>
<body>
    <h1>НОВОСТИ</h1>
    <table>
        <tr style="background:#ececec;">
            <td style="width:5%;">№</td>
            <td>Изображение</td>
            <td>Заголовок</td>
            <td>Url</td>
            <td>Дата</td>
        </tr>
        <?php foreach ($NewsList as $news): ?>
            <tr>
                <td style="width:5%;"><?php echo $news['id']; ?></td>
                <td style="width:150px;">
                    <img src="/img/<?php echo $news['img_url']; ?>" style="width:150px;">
                </td>
                <td><?php echo $news['title'];?></td>
                <td><?php echo $news['url'];?></td>
                <td>
                    <?php
                        $exp = explode('-', $news['date']);
                        $date = $exp[2].'.'.$exp[1].'.'.$exp[0];
                        echo "<i>".$date."</i>";
                    ?>
                </td>
            </tr>
        <?php endforeach; ?>
    </table>
    <br>

 

Тут мы будем выводить нумерацию страниц. Нумерация будет выводиться в виде маркированного списка li. Нам нужно чтобы нумерация выводилась в строчку и без маркировки. Для этого мы будем использовать CSS.

Задаем стиль списку li находящемуся в классе pagination. С помощью list-style-type мы убираем маркеры, с помощью float: left мы поставим все элементы в строчку. margin-right задаст расстояние между номерами в три пикселя. Далее внутри блока, с помощью PHP конструкции выведем pagination, который мы создали в контроллере:

    <style>
        .pagination li {
            list-style-type: none;
            float: left;
            margin-right: 3px;
        }
    </style>
    <div class="pagination" style="margin-left:20%;"><?php echo $pagination->get(); ?></div>
</body>
</html>

 

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

Сам класс Pagination.php. Его нужно будет создать в папке components:

<?php
class Pagination
{
    /**
     * @var Ссылок навигации на страницу
     */
    private $max = 10;
    /**
     * @var Ключ для GET, в который пишется номер страницы
     */
    private $index = 'page';
    /**
     * @var Текущая страница
     */
    private $current_page;
    /**
     * @var Общее количество записей
     */
    private $total;
    /**
     * @var Записей на страницу
     */
    private $limit;
    /**
     * Запуск необходимых данных для навигации
     * @param type $total <p>Общее количество записей</p>
     * @param type $currentPage <p>Номер текущей страницы</p>
     * @param type $limit <p>Количество записей на страницу</p>
     * @param type $index <p>Ключ для url</p>
     */
    public function __construct($total, $currentPage, $limit, $index)
    {
        # Устанавливаем общее количество записей
        $this->total = $total;
        # Устанавливаем количество записей на страницу
        $this->limit = $limit;
        # Устанавливаем ключ в url
        $this->index = $index;
        # Устанавливаем количество страниц
        $this->amount = $this->amount();
        # Устанавливаем номер текущей страницы
        $this->setCurrentPage($currentPage);
    }
    /**
     *  Для вывода ссылок
     * @return HTML-код со ссылками навигации
     */
    public function get()
    {
        # Для записи ссылок
        $links = null;
        # Получаем ограничения для цикла
        $limits = $this->limits();
        $html = '<ul class="pagination">';
        # Генерируем ссылки
        for ($page = $limits[0]; $page <= $limits[1]; $page++) {
            # Если текущая это текущая страница, ссылки нет и добавляется класс active
            if ($page == $this->current_page) {
                $links .= '<li class="active"><a href="">' . $page . '</a></li>';
            } else {
                # Иначе генерируем ссылку
                $links .= $this->generateHtml($page);
            }
        }
        # Если ссылки создались
        if (!is_null($links)) {
            # Если текущая страница не первая
            if ($this->current_page > 1)
            # Создаём ссылку "На первую"
                $links = $this->generateHtml(1, '&lt;') . $links;
            # Если текущая страница не первая
            if ($this->current_page < $this->amount)
            # Создаём ссылку "На последнюю"
                $links .= $this->generateHtml($this->amount, '&gt;');
        }
        $html .= $links . '</ul>';
        # Возвращаем html
        return $html;
    }
    /**
     * Для генерации HTML-кода ссылки

     * @param integer $page - номер страницы

     * @return
     */
    private function generateHtml($page, $text = null)
    {
        # Если текст ссылки не указан
        if (!$text)
        # Указываем, что текст - цифра страницы
            $text = $page
        $currentURI = rtrim($_SERVER['REQUEST_URI'], '/') . '/';
        //$currentURI = preg_replace('~/page-[0-9]+~', '', $currentURI);
        $currentURI = preg_replace('~/[0-9]+~', '', $currentURI);
        # Формируем HTML код ссылки и возвращаем
        return
                '<li><a href="' . $currentURI . $this->index . $page . '">' . $text . '</a></li>';
    }
    /**
     *  Для получения, откуда стартовать

     * @return массив с началом и концом отсчёта

     */
    private function limits()
    {
        # Вычисляем ссылки слева (чтобы активная ссылка была посередине)
        $left = $this->current_page - round($this->max / 2);
        # Вычисляем начало отсчёта
        $start = $left > 0 ? $left : 1;
        # Если впереди есть как минимум $this->max страниц
        if ($start + $this->max <= $this->amount) {
        # Назначаем конец цикла вперёд на $this->max страниц или просто на минимум
            $end = $start > 1 ? $start + $this->max : $this->max;
        } else {
            # Конец - общее количество страниц
            $end = $this->amount;
            # Начало - минус $this->max от конца
            $start = $this->amount - $this->max > 0 ? $this->amount - $this->max : 1;
        }
        # Возвращаем
        return
                array($start, $end);
    }
    /**
     * Для установки текущей страницыу

     * @return
     */
    private function setCurrentPage($currentPage)
    {
        # Получаем номер страницы
        $this->current_page = $currentPage;
        # Если текущая страница больше нуля
        if ($this->current_page > 0) {
            # Если текущая страница меньше общего количества страниц
            if ($this->current_page > $this->amount)
            # Устанавливаем страницу на последнюю
                $this->current_page = $this->amount;
        } else
        # Устанавливаем страницу на первую
            $this->current_page = 1;
    }
    /**
     * Для получения общего числа страниц

     * @return число страниц

     */
    private function amount()
    {
        # Делим и возвращаем
        return ceil($this->total / $this->limit);
    }
}
Grai Просмотров сегодня +5 27 июня 2017 команда сайта
Реклама помогает поддерживать
и развивать наш сервис.


Подробнее
(ссылка откроется в новой вкладке)
  Реклама