Как на 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, '<') . $links;
# Если текущая страница не первая
if ($this->current_page < $this->amount)
# Создаём ссылку "На последнюю"
$links .= $this->generateHtml($this->amount, '>');
}
$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);
}
}

Ещё пока нет комментариев, будь первым!
🔔 Отдохните не много, может Вам будет интересно прочитать статьи пользователей нашего сайта.
Как узнать ID последней вставленной записи
Как разрезать изображение на части и склеить обратно из фрагментов, используя PHP и Ajax
Тег b - это полужирный шрифт
Подключение к БД и вывод результата на PHP через PDO на MVC
Как на MVC и PHP сделать вывод новостей из БД с использованием пагинации
В какие каталоги добавить свой сайт бесплатно
Как сделать добавление новостей на сайте при помощи MVC и PHP
Тег audio - это управление аудиофайлом
Как создать модуль онлайн консультации с использованием чата на ajax и php
Тег area - это область ссылки
Как сделать алгоритм поиска по нескольким словам на PHP из БД
Тег caption - это заголовок таблицы