Постраничный вывод массива

В случаях, когда нужно вывести большой PHP-массив постранично, без использования баз данных.

Для такой задачи удобнее всего использовать PHP-класс, который автоматически рассчитает и выведет навигацию c ссылками ?page=2, ?page=3 и т.д.

1
class ArrayPaginator
{
	public  $page    = 1;   /* Текущая страница */
	public  $amt     = 0;   /* Кол-во страниц */
	public  $limit   = 10;  /* Кол-во элементов на странице */
	public  $total   = 0;   /* Общее кол-во элементов */
	public  $display = '';	/* HTML-код навигации */

	private $url     = '';       
	private $carrier = 'page';

	/**
	 * Конструктор.
	 */
	public function __construct($url, $limit = 0)
	{
		$this->url = $url;		
		
		if (!empty($limit)) {
			$this->limit = $limit;
		}		

		$page = intval(@$_GET['page']);
		if (!empty($page)) {
			$this->page = $page;
		}

		$query = parse_url($this->url, PHP_URL_QUERY);
		if (empty($query)) {
			$this->carrier = '?' . $this->carrier . '=';
		} else {
			$this->carrier = '&' . $this->carrier . '=';
		}
	}

	/**
	 * Срез массива и формирование HTML-кода навигации в переменную display.
	 */
	public function getItems($array)
	{
		$this->total = count($array);
		$this->amt = ceil($this->total / $this->limit);	
		if ($this->page > $this->amt) {
			$this->page = $this->amt;
		}

		if ($this->amt > 1) {
			$adj = 2;	
			$this->display = '<nav class="pagination-row"><ul class="pagination justify-content-center">';

			/* Назад */
			if ($this->page == 1) {
				$this->addSpan('«', 'prev disabled');
			} elseif ($this->page == 2) {
				$this->addLink('«', '', 'prev');
			} else {
				$this->addLink('«', $this->carrier . ($this->page - 1), 'prev');
			}

			if ($this->amt < 7 + ($adj * 2)) {
				for ($i = 1; $i <= $this->amt; $i++){
					$this->addLink($i, $this->carrier . $i);			
				}
			} elseif ($this->amt > 5 + ($adj * 2)) {
				$lpm = $this->amt - 1;
				if ($this->page < 1 + ($adj * 2)){
					for ($i = 1; $i < 4 + ($adj * 2); $i++){
						$this->addLink($i, $this->carrier . $i);
					}
					$this->addSpan('...', 'separator');	
					$this->addLink($lpm, $this->carrier . $lpm);
					$this->addLink($this->amt, $this->carrier . $this->amt);	
				} elseif ($this->amt - ($adj * 2) > $this->page && $this->page > ($adj * 2)) {
					$this->addLink(1);
					$this->addLink(2, $this->carrier . '2');
					$this->addSpan('...', 'separator');	
					for ($i = $this->page - $adj; $i <= $this->page + $adj; $i++) {
						$this->addLink($i, $this->carrier . $i);
					}
					$this->addSpan('...', 'separator');	
					$this->addLink($lpm, $this->carrier . $lpm);
					$this->addLink($this->amt, $this->carrier . $this->amt);	
				} else {
					$this->addLink(1, '');
					$this->addLink(2, $this->carrier . '2');
					$this->addSpan('...', 'separator');	
					for ($i = $this->amt - (2 + ($adj * 2)); $i <= $this->amt; $i++) {
						$this->addLink($i, $this->carrier . $i);
					}
				}
			}

			/* Далее */
			if ($this->page == $this->amt) {
				$this->addSpan('»', 'next disabled');				
			} else {			
				$this->addLink('»', $this->carrier . ($this->page + 1));
			}

			$this->display .= '</ul></nav>';
		}

		$start = ($this->page != 1) ? $this->page * $this->limit - $this->limit : 0;		
		return array_slice($array, $start, $this->limit);	
	}

	private function addSpan($text, $class = '')
	{
		$class = 'page-item ' . $class;
		$this->display .= '<li class="' . trim($class) . '"><span class="page-link">' . $text . '</span></li>';		
	}	

	private function addLink($text, $url = '', $class = '')
	{
		if ($text == 1) {
			$url = '';
		}

		$class = 'page-item ' . $class . ' ';
		if ($text == $this->page) {
			$class .= 'active';
		}
		$this->display .= '<li class="' . trim($class) . '"><a class="page-link" href="' . $this->url . $url . '">' . $text . '</a></li>';
	}	
	
	/**
	 * Метод для title страниц.
	 */
	public function getTitle()
	{
		if ($this->page > 1) {
			return ' - страница ' . $this->page;
		} else {
			return '';
		}
	}
}
PHP
2

Имеется следующий PHP-массив:

$prods = array(
	array(
		'name'  => 'Товар №1',
		'price' => '5100',
		'img'   => '1.jpg',
	),
	array(
		'name'  => 'Товар №2',
		'price' => '5100',
		'img'   => '2.jpg',
	),
	...
	array(
		'name'  => 'Товар №100',
		'price' => '5100',
		'img'   => '100.jpg',
	)
);
PHP

Создадим экземпляра класса, и получим срез массива для текущей страницы, далее выведем его.

<?php
$peger = new ArrayPaginator('https://example.com/', 10); 
$items = $peger->getItems($prods);

/* Заголовок или title страницы */
echo '<h1>Зонты' . $peger->getTitle() . '</h1>';

/* Инфо о текущей странице */
echo '<p>Страница ' . $peger->page . ' из ' . $peger->amt . '</p>';	

/* Вывод текста только на первой странице */
if ($peger->page == 1) {
	echo '<p>Описание на первой странице</p>';
}
?>

<div class="prod-list">
	<?php foreach ($items as $row): ?>
	<div class="prod-item">
		<div class="prod-item-img">
			<a href="#"><img src="/img/<?php echo $row['img']; ?>" alt=""></a>			
		</div>
		<div class="prod-item-name">
			<a href="#"><?php echo $row['name']; ?></a>			
		</div>
		<div class="prod-item-price">
			<?php echo $row['price']; ?> р.
		</div>	
		<div class="prod-item-btn">
			<a href="#">Купить</a>
		</div>
	</div>
	<?php endforeach; ?>
</div>

<?php echo $peger->display; ?>
HTML

CSS стили для пагинации:

.pagination-row {
	overflow: hidden;
	clear: both;
	margin: 0 0 20px 0;
	margin-bottom: 15px;
}
.pagination {
	padding: 0;
	margin: 0;
	text-align: center;
 }
.pagination .page-item {
	display: inline-block;
	margin: 0 2px 3px;
}
.pagination .page-link {
	display: inline-block;
	height: 28px;
	min-width: 28px;
	line-height: 28px;
	font-size: 15px;
	text-decoration: none;
	text-align: center;
	border: 1px solid #ddd;
	border-radius: 3px;    
	background: #fbfbfb;
	text-decoration: none;
	color: #000;
}
.pagination a.page-link:hover {
	background: #ffd57b;
}
.pagination .active a.page-link {
	background: #ffae00;
	border-color: #c19432;
}
.pagination .separator .page-link {
	border-color: #fff;
	background: #fff;
}
.pagination .disabled .page-link {
	color: #999;
}
CSS

Результат:

3

Пагинатор уже адаптирован и имеет все необходимые классы под стили Bootstrap.

12.03.2020, обновлено 04.12.2021
14217

Комментарии

, чтобы добавить комментарий.

Другие публикации

Как получить текущий URL в PHP?
Сформировать текущий адрес страницы можно с помощью элементов массива $_SERVER. Рассмотрим на примере URL...
197842
+15
Календарь на PHP
PHP-класс для вывода календаря на месяц, год или любой другой интервал с возможностью выделить отдельные даты и вывести к ним подсказки.
34594
+12
Яндекс.Доставка работа с API в PHP
Примеры работы с API Яндекс.Доставки (для заказа перевозки грузов корпоративным клиентам).
9934
+5
Генерация счета на оплату PDF PHP
С помощью расширения dompdf можно легко сформировать PDF файл. По сути, dompdf - это конвертер HTML в PDF который...
70975
+35
Пример парсинга html-страницы на phpQuery
phpQuery – это удобный HTML парсер взявший за основу селекторы, фильтры и методы jQuery, которые позволяют...
67722
+27
PHP-класс обертка для PDO
Класс значительно упрощает работу с PDO, сокращает код. Реализован на статических классах и не требует создание экземпляра класса.
24329
+12