Постраничный вывод на 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 для постраничной разбивки, который запускается при заходе пользователя на страницу объявлений.

  1. первым делом при запуске скрипта смотрим какую страницу запрашивает пользователь (в нашем примере на это указывает параметр page_number);
  2. на основании номера запрашиваемой страницы вычисляем параметр offset оператора LIMIT ;
  3. запускаем запрос выборки объявлений с оператором LIMIT offset, 20 (где, 20 — это количество отображаемых объявлений на странице в нашем примере);
  4. получаем общее число объявлений в базе;
  5. на основании пункта 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 .

«Постраничный вывод на PHP»

На форуме CodeNet.Ru неоднократно задавали вопрос о том, как сделать постраничный вывод на PHP. Я объяснял, что такое LIMIT, и как его использовать в MySql.

Но все время оказывалось, что вопрос касался только навигации по страницам:

Вот универсальная процедура, выводящая такой блок ссылок:

  • $records — всего записей
  • $r_start — текущая страница
  • $URL — адрес, заканчивающийся на «=»
  • $inpage — записей на страницу

Оставить комментарий

Комментарии

Привет всем помогите сделать постраничный вывод для гостевой
Это сам вывод с гостевой как его разбить постранично потому что много собирается
у тех примерах я шотоникак немогу разобраться молодой в этом деле

Илон Маск рекомендует:  Что такое код get_object_vars

Спасибо автору за статейку. Поставил, но нашел несколько моментов, где можно было код оптимизировать. и добавить комментариев ;)

[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 »

«;

while ($i get_current_length()) <

echo »

«;

А воттак даже чють быстрее получается и без избыточности и перехлесте условий

if ($records%$inpage==0) $add=0; else $add=1;

if ($r_start =5 and $r_start ($ggg-5)) <

if ($records%$inpage==0) $add=0; else $add=1;
$ggg=(intval($records/$inpage)+$add);

Код конечно хороший но у меня почему-то на второй странице выводит вместо 10 указаных на страницу 20.

может я неправиьлно делаю цикл вывода while($list=mysql_fetch_array($list_result)).

$page_posts = 10; // Количество файлов на страницу

$query=»SELECT something FROM table LIMIT

2Fluffy Fear
проше так $str = substr($str, 0, -3);

Заметил в коде как минимум 2 недоделки.

1-я(эстетичская):
После начальных » =5)

В ORACLE нет ключевого слова LIMIT. Как «выкрутиться» из этого положения:

SELECT t1.rn, t1.col1 FROM
(
SELECT rownum rn, col1 FROM Table1
) t1
WHERE t1.rn BETWEEN 11 AND 20;

Подробнее написано здесь:
http://www.arrowsent.com/oratip/tip41.htm

но если нужно выбрать много колонок, то проще так:

SELECT * FROM
(
SELECT rownum rn, col1, col2, col3 FROM table
WHERE rownum = 11;

Примечание: в последнем варианте сортировку (ORDER BY) нельзя выносить за скобки (т.е. во внешний запрос), иначе сортировка будет неправильной.

Блог web-мастера

PHP, MySQL, JavaScript, AJAX, HTML и CSS

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

Как сделать постраничный вывод из MySQL: по 10 (20, 30) записей на страницу, а внизу — ссылки на остальные страницы?

Чтобы получить нужные записи, воспользуемся оператором LIMIT, который вызывается с двумя параметрами — с какой записи начинать, и сколько выводить:

Этот запрос вернет записи с первой по 10, поскольку нумерация начинается с 0. Cоответственно, запросы для второй и третьей страницы будут выглядеть

Как видите, нам надо лишь передать в скрипт число, которое потом подставить в запрос.

Для построения постраничной навигации нам еще понадобится общее число записей в таблице. Это можно сделать с помощью запроса

Далее определим, сколько всего получится страниц:

Здесь используется константа ITEMS_PER_PAGE, в которой хранится количество выводимых на странице записей.

$dblocation = «localhost» ; // Имя сервера
$dbuser = «root» ; // Имя пользователя
$dbpswrd = «» ; // Пароль
$dbname = «catalog» ; // Имя базы данных

DEFINE ( ‘ITEMS_PER_PAGE’ , 5 ) ;

// Соединение с сервером базы данных
$dblink = mysql_connect ( $dblocation , $dbuser , $dbpswrd ) ;
mysql_query ( ‘SET NAMES cp1251’ ) ;
// Выбираем базу данных
mysql_select_db ( $dbname , $dblink ) ;

// Выбираем из БД общее количество записей
$query = «SELECT COUNT(*) FROM products WHERE 1» ;
$res = mysql_query ( $query ) ;
$total = mysql_result ( $res , 0 , 0 ) ;

// Проверяем передан ли номер текущей страницы
if ( isset ( $_GET [ ‘page’ ] ) ) <
$page = ( int ) $_GET [ ‘page’ ] ;
if ( $page 1 ) $page = 1 ;
> else <
$page = 1 ;
>

// Сколько всего получится страниц
$cnt_pages = ceil ( $total / ITEMS_PER_PAGE ) ;
if ( $page > $cnt_pages ) $page = $cnt_pages ;
// Начальная позиция
$start = ( $page — 1 ) * ITEMS_PER_PAGE;

$query = «SELECT id, title, price
FROM products
ORDER BY price ASC
LIMIT » . $start . «, » .ITEMS_PER_PAGE;
$res = mysql_query ( $query ) ;


// Выводим «шапку» таблицы
echo ‘

Номер строки Значение
«.$pp.» «.$page_array[$i].»
‘ ;
echo ‘
‘ ;
echo ‘

‘ ;
echo ‘

‘ ;
echo ‘

‘ ;
echo ‘

‘ ;

while ( $prd = mysql_fetch_array ( $res ) )
<
echo ‘

‘ ;
echo ‘

‘ ;
echo ‘

‘ ;
echo ‘

‘ ;
echo ‘

‘ ;
>

// Строим постраничную навигацию
if ( $cnt_pages > 1 )
<
echo ‘

// Выводим меню
echo $startpage . $page2left . $page1left . ‘‘ . $page . ‘‘ . $page1right . $page2right . $endpage ;

Тут есть проблема, о которой стоит упомянуть: кроме переменной $page нашему скрипту могут быть переданы и другие переменные. Решается это просто:

и полученную переменную $uri подставляем в код вместо $_SERVER[‘PHP_SELF’]

Комментариев: 17

Что-то не пойму… то есть скрипт великолепный! Спасибо большое, но я что-то не пойму, как развернуть выборку, т.е. не:
1.2.3.4, а:
4.3.2.1.
Буду признателен за совет!

admin:

haZe мне кажется, что вопрос сформулирован не очень правильно. Может быть, есть необходимость выводить записи (например, новостей) в обратном порядке? Т.е. сначала более свежие записи, а потом более старые? Тогда надо просто изменить запрос к базе данных

Если все-таки надо изменить нумерацию страниц, то обрати внимание на строку

Нам никто не мешает ее “развернуть”

Да, Вы правы, более свежие наверх!
Спасибо!

НЕ получается ничего(((

admin:

Аня, не слишком информативный комментарий. Вы не находите? Что не получается? Печатать на компьютере не умеете? Не получается установить Apache+PHP+MySQL? Не выполняется запрос к БД? Что-то еще?

Сделала по-чайниковски — скопировала и заменила на свои данные, но страница даже не загружается. Не пойму, где ошибка.

admin:

Аня, это пустой разговор. “Не получается” — вообще ни о чем не говорит. Какой у Вас уровень знаний? Apache утсанавливать умеете? Что такое PHP знаете? Выполнить запрос через phpMyAdmin умеете? Чем Вам промочь? Выразить сочувствие? Ну, считайте что выразил.

Идёте на форум, выкладываете не работающий скрипт, дамп базы данных, объясняете, что не работает — тогда это будет предметный разговор.

Получилось. Вся проблема была в точке тут: echo ”.$prd[‘id’].”.; Теперь спасибо за скрипт!!))

так что это не у меня ошибка…не ругайтесь уж так на меня))

admin:

Позвольте вопрос? Ошибка не у Вас. А у кого?

У Вас в скрипте лишняя точка, на которую я не сразу обратила внимание:
В разделе “Выводим “шапку” таблицы” в while в строке вывода ID после закрывающего тега

стоит лишняя точка.

admin:

Все, теперь понял. Спасибо, исправил

Сергей:

Хороший скрипт, спасибо.
Есть одна проблема.
Меняю $_SERVER[‘PHP_SELF’] на $uri и скрипт не работает.
Получаю только 1-ю страницу, при клике на другие опять 1-я.
Подскажите начинающему

admin:

Сергей, выкладывайте свой код на форуме, посмотрим, в чем там проблема.

El_Kriton:

С этим кодом все понятно..поставил, работает..спасибо!
А как сделать, чтобы выводились все номера страниц без “…” и чтобы номер открытой страницы не был ссылкой?
заранее спасибо

Сергей 2:

У меня та же проблема, что и у предыдущего Сергея.
“..и полученную переменную $uri подставляем в код вместо $_SERVER[‘PHP_SELF’]..” — этого мало, нужно ещё знаки вопроса постирать из

Отличный код, хоть и старая разработка, но изменил вывод, немного поддизайнил и все норм работает.

Помогите сделать постраничный вывод php mysql [закрыт]

Помогите пожалуйста сделать постраничную навигацию, 4 примера уже попробовал не получается

Закрыт по причине того, что не по теме участниками Dmitriy Simushev, zRrr, cheops, Nicolas Chabanovsky ♦ 13 май ’16 в 7:01 .

Похоже, этот вопрос не соответствует тематике сайта. Те, кто голосовал за его закрытие, указывали следующую причину:

  • «Вопросы с просьбами помочь с отладкой («почему этот код не работает?») должны включать желаемое поведение, конкретную проблему или ошибку и минимальный код для её воспроизведения прямо в вопросе. Вопросы без явного описания проблемы бесполезны для остальных посетителей. См. Как создать минимальный, самодостаточный и воспроизводимый пример.» – Dmitriy Simushev, zRrr, cheops

Если вопрос можно переформулировать согласно правилам, изложенным в справке, отредактируйте его.

2 ответа 2

Самое простое, что можно использовать для постраничного вывода — это LIMIT . Как будто для этого и сделан.

$offset — Самый главной и сложный параметр в этом деле. Он определяет какая страница будет выведена в HTML.
Сервер БД пропускает первые $offset строк(и), выбранных запросом и начинает выдачу результатов, начиная со строки номер $offset + 1 .
$page_size — количество записей на странице. наверное то же, что Ваш $users_on_page .
Сервер выдаст в результате не более этого количества строк.

Важно чтобы был ORDER BY . Порядок должен быть, чтобы не случалось такого, что одни и те же строки будут то на первой, то на десятой странице.

Номер страницы вычисляется по $offset и $page_size :
$page_number = $offset % $page_size . Вроде так.
Можно и по номеру страницы определить требуемый offset:
$offset = ($page_number — 1) * $page_size Количество страниц получают из запроса $countQuery и $page_size :
$page_count = ($count / $page_size) + (($count % $page_size) == 0 ? 0 : 1)

Формируются необходимые кнопки/ссылки навигации. $page_number (от 1 до $page_count ) используется в названии. Надо же как-то показать номер страницы.
Вычисленный $offset используется как параметр, который будет передан обратно на сервер при нажатии на кнопку.
В Вашем примере нет никаких элементов навигации по страницам и я не будут ничего придумывать. Идея и так ясна.

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

ID Наименование Цена
‘ . $prd [ ‘id’ ] . ‘ ‘ . $prd [ ‘title’ ] . ‘ ‘ . $prd [ ‘price’ ] . ‘
01.04.2010, 22:26

Постраничный вывод
Подскажите пожалуйста! На многих сайтах замечал , что в постраничном выводе выделяется любая.

Постраничный вывод
Как сделать постраничный вывод этому скрипту

Постраничный вывод
Здравствуйте, у меня есть постраничный вывод, вот его скрипт: $num_item_pages_list = $armory;.

Постраничный вывод
Добрый вечер. Пишу сайт, нужен постраничный вывод новостей, погуглил, не нашел не чего.

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

Выборки со смещением (LIMIT/OFFSET) могут работать очень медленно при больших значениях смещений. Это происходит по причине того, что MySQL перебирает и отбрасывает все строки результата, пока их количество не будет равно значению OFFSET. Например:


Такой запрос будет использоваться для показа 1000й страницы статей (по 20 статей на страницу). В таком случае, MySQL переберет и отбросит 20 тыс. записей до того, как вернет 20 нужных нам. Естественно, с ростом номера страницы, запрос будет работать все медленнее.

Требования

Обычно реализация постраничного вывода подразумевает:

  • Вывести количество всех результатов (например, всего 234 тыс. статей)
  • Вывести ссылки на страницы результатов (1я, 2я, 3я. 2334я и т.п.)

В стандартном случае все реализуется довольно просто:

Количество всех результатов:

Ссылки на страницы:

Проверка скорости

Проведем эксперимент. В нашей таблице есть 500 000 записей. Выполним ряд запросов со смещением:

Заметно, что второй запрос выполнялся в 10 раз дольше, чем первый. Причем мы рассматриваем достаточно простой вариант, с элементарным запросом и структурой таблицы.

Проблема count(*)

Если Вы используете таблицы InnoDB, то count(*) будет работать очень медленно. Это вторая проблема, которая приводит к замедлению работы постраничной выборки.

Решение первое — избегание

Лучшее решение проблемы — избежать ее:

  1. Действительно ли Вам необходимо показывать пользователю сколько записей было найдено при выборке?
  2. Нужно ли пользователю иметь возможность листать на последние страницы списка? Возможно, следует ограничиться несколькими первыми страницами?
  3. Нужна ли пользователю возможность перейти со страницы 3 на страницу 17? Возможно ему хватит только ссылок «следующая» и «предыдущая»? Это позволит не использовать тяжелый расчет количества доступных страниц.

Решение второе — оптимизация

Стоит подумать о переносе задачи постраничного вывода на другую технологию. Тогда Вы делаете выборку абсолютно всех строк, кэшируете ее и организовываете постраничный вывод на уровне, например, PHP. Для того, что-бы не хранить в кеше результаты огромной выборки, стоит кешировать только первичные ключи записей и список ID:

Попробуйте избавиться от LIMIT OFFSET, если это возможно. Например, можно передавать первичный ключ первой записи на странице, и тогда выборка результатов страницы будет выглядеть так:

Чтобы узнать, нужно ли делать ссылку на след. страницу можно выбрать не 20, а 21 запись. Показывать все равно будем только 20. А отсутствие 21й в результатах будет говорить о том, что ссылка не нужна.

В случае, если таблица меняется редко (несколько раз в сутки), кэшируйте полный результат каждой страницы.

Для замены count(*) можно парсить результаты EXPLAIN. Это даст оценочный результат (с погрешностью около 30%), но сработает намного быстрее.

Самое главное

Стандартная реализация постраничного вывода может быть очень медленной. Откажитесь от списков страниц и показа дальних страниц если это возможно. В другом случае используйте кеширование идентификаторов или замените OFFSET на выборку по ID.

Check-unused-keys для определения неиспользуемых индексов в базе данных

Повышение скорости работы запросов с MySQL Handlersocket

Правильная настройка Mysql под нагрузки и не только. Обновлено.

Что такое индексы в Mysql и как их использовать для оптимизации запросов

Синтаксис и оптимизация Mysql LIMIT

Эффективная замена ORDER BY RAND()

Сравнение Vertica и Mysql на практике

Включение и использование логов ошибок, запросов и медленных запросов, бинарного лога для проверки работы MySQL

Правила выбора типов данных для максимальной производительности в Mysql

Ускорение репликации в Mysql 5.6+

Как восстановить данные, если MySQL упал и не поднимается

Быстрая альтернатива Mysqldump для больших таблиц без блокировок и выключений.

Анализ медленных запросов с помощью EXPLAIN

Правильный поиск по тексту в Mysql (full-text search)

Анализ медленных запросов (профилирование) в MySQL с помощью Percona Toolkit

3 примера установки индексов в JOIN запросах

Рекомендации по настройке Redis для оптимизации ресурсов и повышения стабильности на производственном сервере

Использование партиций для ускорения сложных удалений

Сравнение двух движков и когда стоит использовать каждый из них

И как правильно работать с длительными соединениями в MySQL

Проверка работы Mysql под нагрузкой Sysbench

Настройка Master-Slave репликации на MySQL за 6 простых шагов

Настройки для улучшения производительности Postgres

Примеры использования колоночной базы данных Vertica

Как реализовать постраничный вывод данных из БД (PHP, MySQL) с сортировкой?

Но если делать сортировку через ORDER BY . то получится что я отсортирую только строки, попадающие под условия лимита, а провести ее надо для всей таблицы и только после этого выводить постранично.

Вы понимаете не правильно.
Сначала происходит order by всех строк в результирующей выборке.
Потом через limit определяется сколько и каких строк Вы получите от sql сервера.

Запрос
вернет 10 самых больших 10 id из всей таблицы

Ну и мануал почитайте, там все описано в каком порядке применяется dev.mysql.com/doc/refman/5.7/en/select.html

Гм. а разве лимит накладывается до order .

Для надежности можно конечно вот так сделать:
select * from
(select * from table order by z) as ordered_table
limit x,y


только как мне кажется последовательность применения все-таки WHERE -> GROUP BY -> HAVING -> ORDER BY -> LIMIT

Но если делать сортировку через ORDER BY . то получится что я отсортирую только строки, попадающие под условия лимита

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

Как на MVC и PHP сделать вывод новостей из БД с использованием пагинации

В прошлой статье мы рассматривали, как добавить новости в базу данных. Теперь мы будем выводить эти новости постранично с использование класса Pagination.

Для начала прописываем путь к обработчику страницы.

Теперь создадим сам обработчик в файле NewsController.php. Он по умолчанию получает значение page равное 1, это нужно для того, чтобы пагинация начиналась с первой страницы.

В NewsList с помощью функции getNewsLimit получаем сами новости из таблицы базы данных. В total при помощи функции getCountNews запишется общее количество новостей.

Затем создаем Pagination, он имеет следующий синтаксис: Pagination(общее количество новостей, номер страницы, максимальное количество новостей на странице, ‘символ который будет подставлен в адресную строку перед номером страницы’)

В итоге у нас получится вот такой метод:

Теперь опишем используемые функции и константу:

Константа, в которой задано максимальное количество выводимых новостей на одной странице, ее нужно просто написать внутри класса:

Функция getNewsLimit. По факту это просто запрос в базу данных с последующей записью результат в массив, но есть одно отличие. Мы берем записи из таблицы базы данных со смещением, относительно текущей страницы пагинации и максимального количества записей.

Допустим, мы переходим на третью страницу пагинации, значение переменной page становится равным трем, так как отчет записей с базы данных мы начинаем с нуля. Максимальное количество элементов на странице равно трем. Мы отнимаем от page единицу и умножаем на максимальное количество новостей. Таким образом, мы получаем выражение (3-1)*3, оно равно числу шесть, то есть мы будем брать записи, из БД начиная с шестой по счету.

В переменную limit мы записываем максимальное количество записей на странице. Переменная limit будет указывать, сколько записей мы вытянем из базы данных.

В результате выполнения SQL запроса мы получим limit записей, начиная от offset элемента.

Функция getCountNews. Простой SQL запрос, который считает количество элементов в таблице базы данных по id:

Теперь пришло время создать страницу, на которой мы будем выводить элементы. У меня она выглядит вот так:

С помощью цикла foreach выводим записи на страницу. Массив NewsList мы получаем из обработчика который находится в NewsController. Эта страница имеет следующий листинг:

Тут мы будем выводить нумерацию страниц. Нумерация будет выводиться в виде маркированного списка li. Нам нужно чтобы нумерация выводилась в строчку и без маркировки. Для этого мы будем использовать CSS.

Задаем стиль списку li находящемуся в классе pagination. С помощью list-style-type мы убираем маркеры, с помощью float: left мы поставим все элементы в строчку. margin-right задаст расстояние между номерами в три пикселя. Далее внутри блока, с помощью PHP конструкции выведем pagination, который мы создали в контроллере:

Таким образом, мы получаем вывод новостей из базы данных с пагинацией. Список номеров страниц можно редактировать как вам захочется.

Сам класс Pagination.php. Его нужно будет создать в папке components:

Смотрите также дополнительные статьи про MVC

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

12.02.13 25.01.15 Нет 4694

Как сделать постраничный вывод из MySQL: по 10 (20, 30) записей на страницу, а внизу – ссылки на остальные страницы?

Чтобы получить нужные записи, воспользуемся оператором LIMIT , который вызывается с двумя параметрами – с какой записи начинать, и сколько выводить:

Этот запрос вернет записи с первой по 10, поскольку нумерация начинается с 0. Cоответственно, запросы для второй и третьей страницы будут выглядеть

Как видите, нам надо лишь передать в скрипт число, которое потом подставить в запрос.

Для построения постраничной навигации нам еще понадобится общее число записей в таблице. Это можно сделать с помощью запроса

Далее определим, сколько всего получится страниц:

Здесь используется константа ITEMS_PER_PAGE , в которой хранится количество выводимых на странице записей.

Тут есть проблема, о которой стоит упомянуть: кроме переменной $page нашему скрипту могут быть переданы и другие переменные. Решается это просто:

и полученную переменную $uri подставляем в код вместо $_SERVER[‘PHP_SELF’]

и ещё знаки вопроса постирать из

Может быть, есть необходимость выводить записи (например, новостей) в обратном порядке? Т.е. сначала более свежие записи, а потом более старые? Тогда надо просто изменить запрос к базе данных

Если все-таки надо изменить нумерацию страниц, то обрати внимание на строку

Функции постраничного вывода в PHP

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

Часто при создании динамических сайтов (отсутствуют страницы как таковые) на базе данных или на файлах возникает вопрос о постраничном выводе информации будь — то статьи, архив новостей или что нибудь другое содержащие довльно большое количество страниц.
Поэтому мы начинаем (если сами не сообразим или кто-нибудь не поможет) рыскать по Интернету в поисках нужного кода, но приличный постраничный вывод найти тяжело. Так что попробуем сделать сегодня что нибудь хорошее, а главное рабочее.

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

Вы видите, что функция имеет два входных параметра $start — точка выборки из базы данных и $count — количество данных, в файле либо в базе данных. Эта функция самая простая, так что на неё мало надежды при использовании на крупных сайтах где много информации.

Рассмотрим более сложную функцию, но имеющую больше функциональности.

function PagePrint ( $variable ) <
global $beginPage , $endPage ; //——Объявляем глобальные переменные, отвечающие за ссылку на первую и последнюю страницу
$href = » ; //——Перемменная содержащая в себе постраничный вывод
$separator = ‘ ‘ ; //——Переменная задающая разделитель между ссылками, по умолчанию пробел
$style = ‘style=»text-decoration:none» style=»color:orange» style=»font-weight:bold»‘ ; //——-Задаёт стиль текущей страницы
$stylePage = ‘style=»text-decoration:none» style=»color:blue» style=»font-weight:bold»‘ ; //——Задаёт стиль ссылки на первую и последнюю страницу
if( is_array ( $variable )): //——Проверяем тип array
#Перебираем массив и присваиваем $number — количество записей, $start — точка извлечения, $pageCount — количество записей, $andere — другие свойства ссылки, $class — стиль для ссылок, $showLink — количество ссылок на странице
list( $number , $start , $pageCount , $andere , $class , $showLink )= $variable ;
#Обрабатывам $start
if(empty( $start ) && ! is_int ( $start ) && ! is_numeric ( $start )) $start = 0 ;
else $start = $start ;
#Обрабатываем $number
if(empty( $number ) && ! is_int ( $number ) && ! is_numeric ( $number )) $number = 10 ;
else $number = $number ;

$page =(( $start / 10 )+ 1 ); //——-Рассчитывавем номер страницы
$count = ceil ( $pageCount / $number ); //——Количество страниц

#Вывод сслыки на первую и последнюю страницы
if( $count !== 1 ) :
$beginPage = » ? start = 0 «.$andere.»» » . $stylePage . «>перв» ; //———Первая страница
$endPage = » ? start = «.(($count-1)*10).$andere.»» » . $stylePage . «>посл» ; //——Последняя страница
else: FALSE ;
endif;

if( $pageCount == 10 ): return False ;
else:
#Постраничный вывод
$begin = $page — intval ( $showLink / 2 ); //——Определяет номер страницы с которой выводить
for( $j = 0 ; $j $showLink ; $j ++):
$i = $begin + $j ; //——Номер страницы
#Защищает скрипт если $ if( $i 1 ):
$showLink ++;
continue;
endif;
#Постраничный вывод
if( $i > $count ) break; //——Защита если количество $i>возможных записей
if( $i == $page ) $href = $href . » . $style . » >» . $i . «» ; //——Вывод текущей страницы
else $href = $href . » ? start = «.(($i — 1)*10).$andere.»» » . $class . «>» . $i . » » ; //——Вывод следующих страниц
endfor;
return $href ;
endif;
endif;
>

Входным параметром функции является массив из шести элементов:

$number — количество отображаемых сообщений на странице
$start — точка извлечения из базы данных, т.е номер сообщения с которого начинается зивлечение данных
$pageCount — общее количество записей, т.е сколько всего содержит база записей
$andere — другие параметры ссылки, будь то новые переменные или что-либо ещё
$class — данный параметр задаёт внешний вид ссылок, т.е ссылки на страницы
$showLink — количество ссылок на странице
Первый параметр может быть передан через метод @$_GET[‘number’], только в том случае, если Вы захотите чтобы пользователь мог изменять количество сообщений на странице.
Второй параметр обязательно передаётся в массив методом @$_GET[‘start’], так как параметр $start всё время меняется когда пользователь кликает по ссылке на страницу.

Если, Вы вдруг не захотите, передавать первый, третий, четвёртый, пятый элемент массива вместо них необходимо передать пустоту — », без пробела между кавычками.

Как Вы можете видеть функция сильно расширяет возможности при создании постраничного вывода. Теперь Вы можете разместить свой постраничный вывод на маленьком участке страницы, регулируя количество отображаемых ссылок параметром $showLink. Всё это удобно при создании галлерей, поиска по каталогу сайта или чего-нибудь ещё.
Ниже будут приведены примеры вызова функции:

PagePrint(», @$_GET[‘start’], 90, », », 10) — Всего записей в базе 90, постраничный вывод будет отображать по десять ссылок

PagePrint(@$_GET[‘number’], @$_GET[‘start’], 90, », », 10) — Всего записей в базе 90, постраничный вывод будет отображать по десять ссылок и есть возможность изменять количество отображаемых записей на странице

PagePrint(@$_GET[‘number’], @$_GET[‘start’], 90, ‘&category=1’, », 10) — Всего записей в базе 90, постраничный вывод будет отображать по десять ссылок, есть возможность изменять количество отображаемых записей на странице и ссылка передаёт дополнительную переменную category со значением 1

PagePrint(@$_GET[‘number’], @$_GET[‘start’], 90, ‘&category=1’, ‘style=»color:black»‘, 10) — Всего записей в базе 90, постраничный вывод будет отображать по десять ссылок, есть возможность изменять количество отображаемых записей на странице, ссылка передаёт дополнительную переменную category со значением 1 и ссылки на странице будут чёрного цвета.
Надеюсь приведённые ниже объяснения и комментарии внутри функции помогут разобраться Вам с принципом работы функции.

Илон Маск рекомендует:  Что такое код cpdf_fill_stroke
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL