Постраничная навигация на PHP это очень просто

от автора

Вступление

Очень часто при разработке разных сайтов или модулей приходится использовать — постраничную навигацию. Каждый программист использует свои способы или же готовые библиотеки, но сегодня я наведу пример как можно упростить работу с этой функцией.

Немного теории

В основе работы алгоритма лежит использование SQL — запроса с ключевым словом LIMIT. Для реализации механизма постраничной навигации, нужно: смещение от начальной точки отсчёта — START и число выводимых элементов — LIMIT.

Как же это работает ???
Рассмотрим пример разбивки информации на страницы по 3 — элемента. При такой разбивке мы поочередно будем получать значения с n по n + 3 (размер вывода). Вот наглядная демонстрация:


При такой разбивке мы получаем 3 — страницы:

Значения для загрузки элементов:
Страница 1LIMIT 0,3 (Взять значение с 0 размером 3)
Страница 2LIMIT 3,3 (Взять значение с 3 размером 3)
Страница 3LIMIT 6,3 (Взять значение с 6 размером 3)
и т.д.
По этим значениям мы видим что от страницы, к странице меняется лишь стартовое значение.

Теперь рассмотрим пример вывода навигации по страницам:

1 — Переход на следующую или предыдущую страницу от поточной.
2 — Переход на следующую или предыдущую страницу от крайней внутри.
3 — Активная страница.
4 — Последняя страница.
5 — Сдвиг влево или вправо для отображения страниц относительно текущей.

Практика

Когда мне нужно вывести информацию по страницах я использую свой класс который собрал уже давно. Вот его листинг. Думаю описывать все функции нет смысла. Человек который хоть немного разбирается в PHP все поймет.

Листинг класса

class Paging {   	private $next = 'NEXT';  	private $prev = 'PREV';  	 	private $sql; 	private $base;  	private $cur_pg;  	private $max_pages;  	private $lr_page = 2;  	private $in_page = 10; 	  	public function __construct($base, $page = 'page')  	{  		$this->base   	= $base;  		$this->page   	= $page;  		$this->cur_pg 	= isset($_GET[$this->page]) && (int)$_GET[$this->page] > 0 ? (int)$_GET[$this->page] : 1;  	}  	public function set_in_page($psize)  	{  		$this->in_page = abs((int)$psize);  	}   	private function parse_sql()  	{  		$query = $this->sql;  		 		if ($this->in_page != 0) {  			$limit = ($this->cur_pg - 1) * $this->in_page;  			$query = preg_replace('/^SELECT\s+/i', 'SELECT SQL_CALC_FOUND_ROWS ', $this->sql)." LIMIT $limit,".$this->in_page;  		}  		return $query;  	}   	public function load_list()  	{  		if (!isset($this->max_pages)) return '';  		$lnk_list = array();   		$start = $this->cur_pg - $this->lr_page;   		$end   = $this->cur_pg + $this->lr_page;  		if ( $start < 1 ) $start = 1; 		 		if ( $end > $this->max_pages ) $end = $this->max_pages;   		if ( $start > 1 )  $lnk_list[] = $this->parse_url($start-1, $start - 2 > 0 ? '...' : '' );  		for ($i = $start;  $i <= $end; $i++) $lnk_list[] = $this->parse_url($i);  		if ( $end + 1 <  $this->max_pages )  $lnk_list[] = $this->parse_url($end +1, $end + 2 == $this->max_pages ? '' : '...');  		if ( $end + 1 <= $this->max_pages )  $lnk_list[] = $this->parse_url($this->max_pages);   		return implode(' ', $lnk_list);  	}   	private function parse_url($page, $text = '')  	{  		if (!$text) $text = $page;  		if ($page != $this->cur_pg) { 			parse_str($_SERVER['QUERY_STRING'], $qstr); 			$qstr[$this->page] = $page; 			return '<a href="?'.http_build_query($qstr).'" class="next_page">'.$text.'</a>'; 		} else { 		return '<span class="current_page">'.$text.'</span>'; } 	}   	public function show_table_tpl($sql, $tpl, $paging = true) 	{ 		$html 		= ''; 		$this->sql 	= $sql;  		$table 		= $this->base->query($this->parse_sql());  		$row 		= mysqli_fetch_row($this->base->query('SELECT FOUND_ROWS()')); 		if ($this->in_page !== 0) $this->max_pages = ceil(array_pop($row) / $this->in_page);  		  		if ($this->cur_pg > $this->max_pages) { $this->cur_pg = $this->max_pages; } 	  		 		$fields = $table->fetch_fields(); 		while($row = $table->fetch_assoc()) 		{ 			$template = $tpl; 			foreach ($fields as $val) { 				$template = preg_replace('#{'.$val->name.'}#', $row[$val->name], $template); 			} 			$html .= $template; 		} 		if ($paging == true) {  			$html .= isset($this->max_pages) && $this->cur_pg > 1 ? $this->parse_url($this->cur_pg - 1, $this->prev) : '';  			$html .= ' '.$this->load_list().' '; 			$html .= isset($this->max_pages) && $this->cur_pg < $this->max_pages ? $this->parse_url($this->cur_pg + 1, $this->next) : '';  		}		 		return $html;	 	}    }  

Использовать его следующим образом:

$PAGE = new Paging($base); // Создание класса и передача ему объекта базы $PAGE->set_in_page(5);	// Установка количества элементов на странице  $tpl = "<div><h1>{title} [{id}]</h1> {title} {title} {title}<br>{title} {title} {title}</div><br>";  // шаблон вывода каждого элемента  echo $PAGE->show_table_tpl('SELECT * FROM news ORDER BY `id` ASC', $tpl); // Загрузка и отображение всей информации 

Значения в {} это название полей таблицы текущего элемента.
При создании класса передается 2 — параметры
— объекта базы;
— указатель на номер страницы.

В show_table_tpl передаются 3 параметры:
— запрос;
— шаблон отображения;
— параметр paging который скрывает номера страниц.

Результат

Немного наглядности:

Ну вот и все. Всем спасибо за внимание!!!

ссылка на оригинал статьи http://habrahabr.ru/post/214383/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *