Постраничный вывод из MySQL
Как сделать постраничный вывод из MySQL: по 10 (20, 30) записей на страницу, а внизу - ссылки на остальные страницы?
Чтобы получить нужные записи, воспользуемся оператором LIMIT, который вызывается с двумя параметрами - с какой записи начинать, и сколько выводить:
Этот запрос вернет записи с первой по 10, поскольку нумерация начинается с 0. Cоответственно, запросы для второй и третьей страницы будут выглядеть
SELECT id, title FROM items LIMIT 20, 10;
Как видите, нам надо лишь передать в скрипт число, которое потом подставить в запрос.
Для построения постраничной навигации нам еще понадобится общее число записей в таблице. Это можно сделать с помощью запроса
$res = mysql_query( $query );
$total = mysql_result( $res, 0, 0 );
Далее определим, сколько всего получится страниц:
Здесь используется константа 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 '<table border="1" cellpadding="5" cellspacing="0">';
echo '<tr>';
echo '<th>ID</th>';
echo '<th>Наименование</th>';
echo '<th>Цена</th>';
echo '</tr>';
while( $prd = mysql_fetch_array( $res ) )
{
echo '<tr>';
echo '<td>'.$prd['id'].'</td>';
echo '<td>'.$prd['title'].'</td>';
echo '<td>'.$prd['price'].'</td>';
echo '</tr>';
}
echo '</table>';
// Строим постраничную навигацию
if ( $cnt_pages > 1 )
{
echo '<div style="margin:1em 0"> Страницы: ';
// Проверяем нужна ли стрелка "В начало"
if ( $page > 3 )
$startpage = '<a href="'.$_SERVER['PHP_SELF'].'?page=1"><<</a> ... ';
else
$startpage = '';
// Проверяем нужна ли стрелка "В конец"
if ( $page < ($cnt_pages - 2) )
$endpage = ' ... <a href="'.$_SERVER['PHP_SELF'].'?page='.$cnt_pages.'">>></a>';
else
$endpage = '';
// Находим две ближайшие станицы с обоих краев, если они есть
if ( $page - 2 > 0 )
$page2left = ' <a href="'.$_SERVER['PHP_SELF'].'?page='.($page - 2).'">'.($page - 2).'</a> | ';
else
$page2left = '';
if ( $page - 1 > 0 )
$page1left = ' <a href="'.$_SERVER['PHP_SELF'].'?page='.($page - 1).'">'.($page - 1).'</a> | ';
else
$page1left = '';
if ( $page + 2 <= $cnt_pages )
$page2right = ' | <a href="'.$_SERVER['PHP_SELF'].'?page='.($page + 2).'">'.($page + 2).'</a>';
else
$page2right = '';
if ( $page + 1 <= $cnt_pages )
$page1right = ' | <a href="'.$_SERVER['PHP_SELF'].'?page='.($page + 1).'">'.($page + 1).'</a>';
else
$page1right = '';
// Выводим меню
echo $startpage.$page2left.$page1left.'<strong>'.$page.'</strong>'.$page1right.$page2right.$endpage;
echo '</div>';
}
?>
Тут есть проблема, о которой стоит упомянуть: кроме переменной $page нашему скрипту могут быть переданы и другие переменные. Решается это просто:
if (count($_GET)) {
foreach ($_GET as $k => $v) {
if ($k != "page") $uri.=urlencode($k)."=".urlencode($v)."&";
}
}
и полученную переменную $uri подставляем в код вместо $_SERVER['PHP_SELF']
haZe:
Что-то не пойму… то есть скрипт великолепный! Спасибо большое, но я что-то не пойму, как развернуть выборку, т.е. не:
20 Август 2008, 23:241.2.3.4, а:
4.3.2.1.
Буду признателен за совет!
admin:
haZe мне кажется, что вопрос сформулирован не очень правильно. Может быть, есть необходимость выводить записи (например, новостей) в обратном порядке? Т.е. сначала более свежие записи, а потом более старые? Тогда надо просто изменить запрос к базе данных
FROM news
ORDER BY puttime DESC
LIMIT ".$start.", ".ITEMS_PER_PAGE;
$res = mysql_query( $query );
Если все-таки надо изменить нумерацию страниц, то обрати внимание на строку
Нам никто не мешает ее “развернуть”
haZe:
Да, Вы правы, более свежие наверх!
3 Сентябрь 2008, 16:35Спасибо!
Аня:
НЕ получается ничего(((
10 Октябрь 2008, 12:14admin:
Аня, не слишком информативный комментарий. Вы не находите? Что не получается? Печатать на компьютере не умеете? Не получается установить Apache+PHP+MySQL? Не выполняется запрос к БД? Что-то еще?
10 Октябрь 2008, 13:04Аня:
Сделала по-чайниковски - скопировала и заменила на свои данные, но страница даже не загружается. Не пойму, где ошибка.
10 Октябрь 2008, 13:31admin:
Аня, это пустой разговор. “Не получается” - вообще ни о чем не говорит. Какой у Вас уровень знаний? Apache утсанавливать умеете? Что такое PHP знаете? Выполнить запрос через phpMyAdmin умеете? Чем Вам промочь? Выразить сочувствие? Ну, считайте что выразил.
Идёте на форум, выкладываете не работающий скрипт, дамп базы данных, объясняете, что не работает - тогда это будет предметный разговор.
10 Октябрь 2008, 13:50Аня:
Получилось!!!! Вся проблема была в точке тут: echo ”.$prd['id'].”.; Теперь спасибо за скрипт!!))
10 Октябрь 2008, 13:50Аня:
так что это не у меня ошибка…не ругайтесь уж так на меня))
10 Октябрь 2008, 13:52admin:
Позвольте вопрос? Ошибка не у Вас. А у кого?
10 Октябрь 2008, 14:00Аня:
У Вас в скрипте лишняя точка, на которую я не сразу обратила внимание:
10 Октябрь 2008, 14:08В разделе “Выводим “шапку” таблицы” в while в строке вывода ID после закрывающего тега </td> стоит лишняя точка.
admin:
Все, теперь понял. Спасибо, исправил
10 Октябрь 2008, 14:10Сергей:
Хороший скрипт, спасибо.
17 Апрель 2009, 22:58Есть одна проблема.
Меняю $_SERVER['PHP_SELF'] на $uri и скрипт не работает.
Получаю только 1-ю страницу, при клике на другие опять 1-я.
Подскажите начинающему
admin:
Сергей, выкладывайте свой код на форуме, посмотрим, в чем там проблема.
18 Апрель 2009, 12:38El_Kriton:
С этим кодом все понятно..поставил, работает..спасибо!
19 Май 2009, 22:46А как сделать, чтобы выводились все номера страниц без “…” и чтобы номер открытой страницы не был ссылкой?
заранее спасибо
Сергей 2:
У меня та же проблема, что и у предыдущего Сергея.
“..и полученную переменную $uri подставляем в код вместо $_SERVER['PHP_SELF']..” - этого мало, нужно ещё знаки вопроса постирать из
$page1right = ' | <a href="'.$_SERVER['PHP_SELF'].'?page='.($page + 1).'">'.($page + 1).'</a>';
...
Stas:
Отличный код, хоть и старая разработка, но изменил вывод, немного поддизайнил и все норм работает.
11 Август 2012, 15:55