Вступление
Очень часто при разработке разных сайтов или модулей приходится использовать — постраничную навигацию. Каждый программист использует свои способы или же готовые библиотеки, но сегодня я наведу пример как можно упростить работу с этой функцией.
Немного теории
В основе работы алгоритма лежит использование SQL — запроса с ключевым словом LIMIT. Для реализации механизма постраничной навигации, нужно: смещение от начальной точки отсчёта — START и число выводимых элементов — LIMIT.
Как же это работает ???
Рассмотрим пример разбивки информации на страницы по 3 — элемента. При такой разбивке мы поочередно будем получать значения с n по n + 3 (размер вывода). Вот наглядная демонстрация:
При такой разбивке мы получаем 3 — страницы:
Значения для загрузки элементов:
Страница 1 — LIMIT 0,3 (Взять значение с 0 размером 3)
Страница 2 — LIMIT 3,3 (Взять значение с 3 размером 3)
Страница 3 — LIMIT 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('/^SELECTs+/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 который скрывает номера страниц.
Результат
Немного наглядности:
Ну вот и все. Всем спасибо за внимание!!!
Автор: Vaskevych