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

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

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

Код класса ArrayPaginator

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

Использование класса

Имеется следующий 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 .separator .page-link {
	border-color: #fff;
	background: #fff;
}
.pagination .disabled .page-link {
	color: #999;
}
CSS

Результат:

Стиль Bootstrap

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

12.03.2020

Комментарии

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

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

Шаблонизатор Smarty
Smarty это компилирующий обработчик шаблонов для PHP позволяющий отделить логику и HTML-верстку веб-приложения.
12.07.2018
4169
+1
Создание товарной накладной в Excel на PHPExcel
Пример как сформировать товарную накладную в с помощью класса PHPExcel. Скачать класс можно с официального сайта или...
27.01.2017
7644
+3
Класс обертка для PDO
Класс значительно упрощает работу с PDO, сокращает код. Реализован на статических классах и не требует создание экземпляра класса.
14.03.2018
6586
+1
Contenteditable – текстовый редактор
Если добавить атрибут contenteditable к элементу, его содержимое становится доступно для редактирования пользователю, а...
12.12.2019
1763
+6
Использование API Яндекс Диска на PHP
Можно найти множество применений Яндекс Диска на своем сайте, например, хранение бекапов и отчетов, обновление прайсов,...
29.11.2017
19177
+6
Вывести массив в виде PHP кода
Для вывода массива в виде PHP кода print_r() и var_dump() не подойдут, поэтому поможет функция...
20.09.2019
617
+1