Функции постраничного вывода в PHP
Постраничный вывод (PHP и MySQL)
Довольно часто на сайте возникает необходимость в отображении большого объема однотипной информации, при этом, для удобства восприятия, её следует разбивать на части, т.е. реализовать постраничный просмотр этой информации. Данное решение используется поисковыми системами при отображении результатов поиска, форумами, досками объявлений и т.д. Данная статья описывает то, как используя MySQL и PHP реализовать постраничный вывод.
Для начала отмечу, что статья не учит работе с базой данных и PHP, а даёт объяснение реализации, и приводит готовый к использованию PHP класс для постраничной разбивки (постраничной навигации).
Начнем! Допустим имеется база данных (MySQL), например, с объявлениями. Нам нужно реализовать их отображение на сайте, порциями по 20 штук на странице. Для перехода же между порциями в нижней части каждой страницы необходимо сформировать ссылки с номерами «порций» (ярлыки страниц):
Выборка данных порциями
Для выборки ВСЕХ объявлений из базы требуется запрос вида:
Конечно, это упрощенный вариант, и в реальных задачах, чаще всего, в запросе присутствуют различные условия (операторы WHERE , ORDER BY . ).
Для того чтобы этот запрос делал выборки порциями, необходимо к нему добавить оператор LIMIT :
Синтаксис оператора LIMIT: LIMIT [offset,] row_count
Необязательный параметр offset сообщает сколько рядов от начала выборки нужно пропустить, а row_count указывает сколько рядов нужно выбрать, т.е. LIMIT 0, 20 (или просто LIMIT 20 опустив нулевой offset) выбирает первые 20 рядов (с 0 по 19 ряд), а LIMIT 40, 20 указывает пропустить 40 (с 0 по 39 ряд) и выбрать следующие 20 (т.е. будут выбраны ряды с номера 40 по 59).
Обращаю ваше внимание, что ряды в выборке нумеруются с нуля, а не с единицы.
Таким образом запросы для нашего примера с объявлениями будут следующими:
и .т.д. offset увеличиваем на 20 для каждой следующей страницы, а row_count всегда равен 20.
Ещё необходимо отметить, что оператор LIMIT в запросе идет по порядку после WHERE , GROUP BY , HAVING , ORDER BY , но если вы новичок в MySQL, то можно сказать, что он идет в конце строки запроса (после него идут операторы довольно редко используемые).
Вторая часть с которой нам нужно разобраться это строка с ярлыками страниц.
Ярлыки страниц
Ярлыки — это ссылки для «перелистывания» страниц, т.е. ссылки нажимая на которые пользователь получает очередную порцию данных. Эти ссылки содержат в качестве параметра номер нужной порции (страницы).
Например, для выборки третьей двадцатки объявлений ярлык может иметь следующий вид:
При клике по этой ссылке запускается скрипт obyavleniya.php, которому доступен параметр page_number, сообщающий, что запрашивается 3 двадцатка объявлений — 3 страница. Скрипт пропускает первые 40 объявлений, и выбирает следующие 20.
Для вывода этой строки ярлыков требуется знать общее число страниц (чтобы знать сколько ярлыков «рисовать»). Его мы можем получить, разделив общее число объявлений на количество объявлений на странице, округлив результат до большего целого. Т.е., если в нашем примере, допустим, всего 107 объявлений, а выводим мы их на каждой странице по 20 штук, то число страниц будет: 107 / 20 = 5.35, т.е. 5 полных страниц (по 20 объявлений) + одна неполная (7 объявлений), итого, округлив получаем 6 страниц (соответственно будет 6 ярлыков).
Для подсчета общего числа объявлений, есть два пути. Первый путь — выполнить отдельный суммирующий запрос практически аналогичного запросу для выборки данных, только без ограничивающего оператора LIMIT , и ненужных операций сортировки ( ORDER BY ), например:
Первый запрос выполняет выборку объявлений, а второй, подсчитывает их общее число функцией COUNT . На практике запросы выборки данных бывают весьма громоздкими и тяжелыми, поэтому дополнительный тяжелый запрос для подсчета не самая «необходимая» операция. Так же этот путь не такой изящный как второй.
В MySQL 4.0.0 появились замечательные вещи, такие как функция FOUND_ROWS и связанная с ней SQL_CALC_FOUND_ROWS — опция оператора SELECT .
Рассмотрим второй вариант подсчета общего числа рядов:
Опять же, первый запрос делает выборку объявлений, а второй получает их общее число, но .
Запрос выборки объявлений в данном случае отличается от выборки из первого варианта только наличием опции SQL_CALC_FOUND_ROWS . Данная опция указывает MySQL вместе с выборкой данных сделать и подсчёт всех тех строк которые бы вернул запрос без оператора LIMIT . Т.е. по сути данный запрос включает в себя в скрытом виде COUNT запрос из первого варианта. При этом сама подсчитанная сумма не возвращается, а запоминается сервером. Теперь, для того чтобы узнать это число, нужно выполнить запрос с функцией FOUND_ROWS (при этом сервер не производит никаких вычислений, просто отдает то, что запомнил раньше).
Второй вариант однозначно выглядит более элегантным, а также может обеспечить некоторый выигрыш по скорости.
Собираем все вместе
Теперь вы знаете все что нужно, и я могу привести алгоритм описывающий логику скрипта obyavleniya.php для постраничной разбивки, который запускается при заходе пользователя на страницу объявлений.
- первым делом при запуске скрипта смотрим какую страницу запрашивает пользователь (в нашем примере на это указывает параметр page_number);
- на основании номера запрашиваемой страницы вычисляем параметр offset оператора LIMIT ;
- запускаем запрос выборки объявлений с оператором LIMIT offset, 20 (где, 20 — это количество отображаемых объявлений на странице в нашем примере);
- получаем общее число объявлений в базе;
- на основании пункта 4 вычисляем общее число страниц объявлений и формируем строку ярлыков.
Вот собственно и всё. Теперь, я надеюсь, вы сможете написать свой скрипт, или воспользоваться моим, понимая суть того как он работает.
PHP класс Paging для постраничной разбивки
Теперь я приведу пример как организуется постраничная навигация с использованием PHP-класса Paging.
Единственное чем данный скрипт отличается от обычного скрипта без постраничной разбивки, так это тем, что запрос выборки данных которые нужно разделить на части производится не через mysqli->query() , а через метод get_page() реализованный в классе Paging, а так же тремя последними строками которые отображают ярлыки и строку отчет о выборке.
Постскриптум
P.S.: Этот постскриптум я привожу скорее для полноты изложения, нежели как реально актуальную информацию для большинства читателей.
Применение SQL_CALC_FOUND_ROWS и FOUND_ROWS() имеет некоторые подводные камни при использовании в UNION-запросах, так как операторы LIMIT могут использоваться в нескольких местах, и могут касаться как отдельных операторов SELECT в составе UNION, так и общего результата UNION в целом. Цель же SQL_CALC_FOUND_ROWS для UNION состоит в подсчёте количества строк, которые будут возвращены без глобального LIMIT . Поэтому следует привести условия применения SQL_CALC_FOUND_ROWS с запросами UNION :
- Ключевое слово SQL_CALC_FOUND_ROWS должно указываться в первом операторе SELECT ;
- Значение FOUND_ROWS() будет точным только при условии применения UNION ALL . Если указано UNION без ALL , происходит исключение дубликатов, и значение FOUND_ROWS() будет лишь приблизительным;
- Если в UNION не присутствует LIMIT , то SQL_CALC_FOUND_ROWS игнорируется и возвращается количество строк во временной таблице, которая создается для выполнения UNION .
Постраничный вывод
Постраничный вывод
Привет. Вот код постраничного вывода записей, оно то работает, но выводит только записи на.
Постраничный вывод
Здравствуйте, у меня есть постраничный вывод, вот его скрипт: $num_item_pages_list = $armory;.
Постраничный вывод
Добрый вечер. Пишу сайт, нужен постраничный вывод новостей, погуглил, не нашел не чего.
Постраничный вывод из бд
Имеенся менюшка — Категория_1 view_cat.php?cat=1 — Категория_2 view_cat.php?cat=2 — Категория_3.
Постраничный вывод
Всем добрый день! Есть код постраничного вывода из БД, все работает, но при нажатии на следующую.
Постраничная навигация php: простой скрипт
С проблемой создания постраничной навигации на языке php сталкиваются многие новички-программисты и не все понимают, как она должна работать. Рассмотрим подробно и по пунктам, как создать самую простую пагинацию.
Для начала представим, что у нас уже есть запрос, который в нужном формате выводит все записи из нужной таблицы.
Разбиваем страницы на нужное количество
Мы получили все записи на странице, но теперь их нужно разбивать. Для разбития на страницы мы добавим в наш запрос — вывод определённого количества записей, с помощью «LIMIT».
- «$art» — показывает с какой записи выводить;
- «$kol» — количество записей для вывода.
Отлично, теперь создадим переменную $page, она будет показывать текущею страницу, на который мы находимся.
К примеру, мы выводим по две записи на страницу, то есть если мы находимся на 1 странице — выводим первые две записи.
Переменную $art мы получаем по формуле — количество записей умножаются на текущую страницу, тем самым мы получаем последнюю запись на текущей странице. И вычитаем «количество записей на страницу».
Определяем страницу, на которой находимся
Теперь у нас для нужной страницы отображаются нужные записи, но нужно ещё определить, на какой мы странице находимся, для этого воспользуемся глобальной переменной $_GET.
Мы получаем текущую страницу через переменную $_GET, а если мы этой переменной нет, то у нас по умолчанию первая страница.
Формируем постраничную навигацию
Для формирования и вывода пагинации нам нужно узнать количество всех записей, найдём это через простой запрос:
Затем нужно узнать, сколько у нас будет страниц:
Делим количество записей на количество выводимых на страницу и округляем до большего числа
Теперь у нас есть всё, чтобы сформировать наши ссылки для навигации, выведем через цикл:
«Постраничный вывод на PHP»
На форуме CodeNet.Ru неоднократно задавали вопрос о том, как сделать постраничный вывод на PHP. Я объяснял, что такое LIMIT, и как его использовать в MySql.
Но все время оказывалось, что вопрос касался только навигации по страницам:
Вот универсальная процедура, выводящая такой блок ссылок:
- $records — всего записей
- $r_start — текущая страница
- $URL — адрес, заканчивающийся на «=»
- $inpage — записей на страницу
Оставить комментарий
Комментарии
Привет всем помогите сделать постраничный вывод для гостевой
Это сам вывод с гостевой как его разбить постранично потому что много собирается
у тех примерах я шотоникак немогу разобраться молодой в этом деле
Спасибо автору за статейку. Поставил, но нашел несколько моментов, где можно было код оптимизировать. и добавить комментариев 😉
[php]
function LeftRight($records,$r_start,$URL,$inpage) <
$str=»»;
if($records =5 and $r_start ($page_count-5)) <
$sstart=$page_count-10;
$send=$page_count;
>
if($sstart $records) $send=[highlight]$page_count[/highlight];
#Выводим список ссылок
for($i=$sstart;$i $page_count or $r_start «.LeftRight($records,r_start,»index.php?start=»,$inpage).» «;
[/php]
/* печатаем единичную ссылку на страницу */
function print_navigation_link ($page_number) <
/* печатаем навигационную полосу */
for ($i=0;$i navig_len;$i++) <
* Класс поддержки навигации информации по страницам.
* Конструктору передается информация , он разбивает ее по страницам.
* @author : Barinov Roman
* @date created : 16.08.2007
* @date modifyed : no
function page_navigation_maker ( $data_income, $step ) <
$this->page_counter = ceil($this->array_len / $this->page_len) ;
/* Получаем страницу длиной в $this->data_step , под номером $page_number */
function get_page ( $page_number ) <
$start_position = ($this->page_len * $page_number);
for ($i=0;$i page_len;$i++) <
if (isset($this->in_array[$i + $start_position])) $arr[] = $this->in_array[$i + $start_position];
/* Получаем количество страниц в списке */
/* Получаем количество Элементов списка */
/* Получаем количество элементов текущего листа */
return ($this->current_page_number) * $this->page_len;
$navig_panel = new page_navigation_printer($page_counter,$_SERVER[‘PHP_SELF’]);
echo »
Номер строки | Значение | |||||||||||||||||||||||||||||||||||||||||||||||||||||
«.$pp.» | «.$page_array[$i].» |
|