Простая постраничная навигация
Всем привет. Данная статья - одна из нескольких, посвящённых такой насущной проблеме, как постраничная навигация. Точнее её решении... точнее о решении, которое посетило меня после недельного раздумья, как сделать эту хрень универсальной, простой в исполнении, простой в интеграции, гибкой в настройке, небольшой по объёму кода и т.п.
Эта статья, для начинающих программистов, профи могут лишь бегло посмотреть, гыкнутьи топать ко второй статье Как сделать постраничную навигацию грамотно - там самое "вкусное" - алгоритм, которым меня недавно осенило, и его реализация. Всё в лучшем виде: просто, надёжно, и довольно оригинально... чёй то я .. ???
Давайте по порядку - сначала уточним термины, которые я буду испльзовать:
Элемент - это то, количество чего нам собственно и нужно разбить на несколько частей (страниц) как правило это статьи/товары в какой либо категории на сайте, но здесь я их буду называть элементами.
Страница - это собственно страница сайта, на которой должно выводиться требуемое количество элементов.
Как сделать постраничную навигацию.
Вспоминаем, для того, что бы получать определённое количество, определённых элементов из базы данных нужно в конец запроса к БД добавить ключевое слово LIMIT, и два параметра: START и LIMIT. Если, что за справкой сюда MySQL 5.0 Reference Manual :: 12.2.8 SELECT Syntax.
Даже если вы работаете не с MySQL - принцип, я думаю останется тот же: что бы реализовать механизм постраничной навигации, нужно иметь как минимум: смещение от начальной точки отсчёта - START и число выводимых элементов - LIMIT. Нагляднее я думаю объяснит рисунок:

Как видим от страницы, к странице меняется лишь значение START - запомним этот факт.
- Это классика, и есть по - моему в любой книжке по PHP...
Общий алгоритм постраничной навигации
Таков: из базы данных мы делаем выборку элементов, упорядоченных по нужному нам критерию, с использованием в SQL - запросе ключевого слова LIMIT. Далее обрабатываем эту выборку удобным способом (например циклом), строя, скажем список ссылок, отличающихся друг от друга только единственным GET- параметром. Назовём его start - он будет содержать это самое смещение START для базы данных. Расчитывается это смещение очень просто: надо умножить номер страницы на чило элементов на странице. Очень удобен для этого цикл FOR с начальным счётчиком равным - 0
В элементарном случае скрипт, стоящий страницы с постраничной навигацией может выглядеть так:
<?php // Объект предоставляющий методы для работы БД // например объект класса PDO $pdo = new PDO('mysql:dbname=... ;'); // Результирующий массив с элементами, выбранными с учётом LIMIT: $items = array(); // Число вообще всех элементов ( без LIMIT ) по нужным критериям. $allItems = 0; // HTML - код постраничной навигации. $html = NULL; // Количество элементов на странице. // В системе оно может определяться например конфигурацией пользователя: $limit = 7; // Количество страничек, нужное для отображения полученного числа элементов: $pageCount = 0; // Содержит наш GET-параметр из строки запроса. // У первой страницы его не будет, и нужно будет вместо него подставить 0!!! $start = isset($_GET['start']) ? intval( $_GET['start'] ) : 0 ; // Некий критерий выборки - показан для естественности примера // В реальности может быть идентификатором какой нибудь категории: $critery = isset($_GET['critery']) ? intval( $_GET['critery'] ) : 0 ; // Запрос для выборки целевых элементов: $sql = 'SELECT ' . ' `table_name`.* ' . 'FROM ' . ' `table_name` ' . 'WHERE ' . ' `critery` = ' . $critery . ' ' . 'LIMIT ' . $start . ', ' . $limit . ' ' . 'ORDER BY ' . ' `critery` '; $stmt = $pdo->query($sql); $items = $stmt->fetchAll(PDO::FETCH_OBJ); if( is_array($items) ) { foreach( $items AS $item ) { // ... ЗДЕСЬ КОД ФОРМИРУЮЩИЙ ВЫВОД ЭЛЕМЕНТОВ ... } } // СОБСТВЕННО, ПОСТРАНИЧНАЯ НАВИГАЦИЯ: // Получаем количество всех элементов: $sql = 'SELECT ' . ' COUNT(*) AS `count` ' . 'FROM ' . ' `table_name` ' . 'WHERE ' . ' `critery` = ' . $critery; $stmt = $pdo->query($sql); $allItems = $stmt->fetch(PDO::FETCH_OBJ)->count; // Здесь округляем в большую сторону, потому что остаток // от деления - кол-во страниц тоже нужно будет показать // на ещё одной странице. $pageCount = ceil( $allItems / $limit); // Начинаем с нуля! Это даст нам правильные смещения для БД for( $i = 0; $i < $pageCount; $i++ ) { // Здесь ($i * $limit) - вычисляет нужное для каждой страницы смещение, // а ($i + 1) - для того что бы нумерация страниц начиналась с 1, а не с 0 $html .= '<li><a href="index.php?category=' . $critery . '&start=' . ($i * $limit) . '">' . ($i + 1) . '</a></li>'; } // Собственно выводим на экран: echo '<ul class="pagination">' . $html . '</ul>';
При переходе по ссылкам постраничной навигации - фактически мы остаёмся на одной и той же странице, но у нас меняются значения GET-переменной $start на основании, которой мы делаем выборку в БД, подставляя её в качестве числа для ключевого слова LIMIT.
Надеюсь идею до новичков я донёс...
... Но это был самый простой случай...
Информация копипастерам
Внимание! Копирование контента с сайта, возможно только с разрешения администратора. Т.е. Меня! Я скорее всего разрешу Вам это сделать, в обмен на живую ссылку, на статью оригинал.