Сайты растут и наполняются информацией, которую группируют чтобы пользователю было удобно ее воспринимать. Для этого весь выводимый контент разделяют, например, на страницы. В общем, делают постраничную навигацию. Такой способ можно увидеть, например, в гостевых книгах, на форумах, в комментариях к статьям, в каталогах и т. п.
Постраничный вывод контента часто становится проблемой перед начинающими PHP-программистами, так же было и у меня. Но давайте, все же, разберемся на примере что к чему.
Для начала, определимся с задачей. Допустим, у нас есть больше тысячи новостей и нам нужно выводить по 10 на каждую страницу. Новости хранятся в базе данных news со следующей структурой:
news_id — номер новости
news_title — заголовок новости
news_text — текст новости
В конечном итоге нам надо получить такую постраничную навигацию:
1 ... 7 8 9 10 11 12 13 ... 100
где 10 — это текущая страница.
Далее, привожу весь код с пояснениями:
<?php
// Функция постраничной навигации
function makepagenav($start, $count, $total, $range = 0, $link = )
{
if ($link == "") { $link = $PHP_SELF."?"; }
$pg_cnt = ceil($total / $count);
if ($pg_cnt <= 1) { return ""; }
$idx_back = $start - $count;
$idx_next = $start + $count;
$cur_page = ceil(($start + 1) / $count);
$res = "Страница ".$cur_page." из ".$pg_cnt.": ";
if($idx_back >= 0) {
if($cur_page > ($range + 1)) {
$res .= "<a href='".$link."rowstart=0'>1</a>...";
}
}
$idx_fst = max($cur_page - $range, 1);
$idx_lst = min($cur_page + $range, $pg_cnt);
if ($range == 0) {
$idx_fst = 1;
$idx_lst = $pg_cnt;
}
for ($i = $idx_fst; $i <= $idx_lst; $i++) {
$offset_page = ($i - 1) * $count;
if ($i == $cur_page) {
$res .= "<span><strong>".$i."</strong></span>";
} else {
$res .= "<a href='".$link."rowstart=".$offset_page."'>".$i."</a>";
}
}
if ($idx_next < $total) {
if ($cur_page < ($pg_cnt - $range)) {
$res .= "...<a href='".$link."rowstart=".($pg_cnt - 1) * $count."'>".$pg_cnt."</a>";
}
}
return "<div>".$res."</div>";
}
// Выводим новости
// Здесь идет подключение к базе данных или что то еще
// ...
// Считаем общее количество новостей
$resultrows = mysql_query("SELECT `news_id` FROM `news`");
$rows = mysql_num_rows($resultrows);
// Пишем количество выводимый новостей на страницу, в нашем случае - 10
$messages_per_page = 10;
// Условие: если запрос GET не существует или он не является числом, то присваеваем ему значение 0
if (!isset($_GET['rowstart']) || !preg_match("/^[0-9]+$/", $_GET['rowstart'])) {
$_GET['rowstart'] = 0;
}
// Выводим по 10 новостей на страницу, где начальной точкой отсчета будет считаться запрос GET
$result = mysql_query("SELECT * FROM `news` ORDER BY `news_id` DESC LIMIT ".$_GET['rowstart'].",".$messages_per_page.);
while ($data = mysql_fetch_assoc($result)) {
echo data['news_title']."<br />";
echo data['news_text']."";
}
// Условие: если общее количество страниц больше, чем нам надо вывести (т.е. больше 10), то выводим список страниц
if ($rows > $messages_per_page) {
echo makepagenav($_GET['rowstart'], $messages_per_page, $rows, 3, $PHP_SELF."?&");
}
?>
Данный способ реализации я взял из CMS PHP-Fusion, т. к. не смог найти ничего лучше подходящего для себя. Что касается вывода ссылок-стрелок на предыдущую/последующую страницу и ссылок-стрелок в начало/конец списка, то можете попробовать дописать код сами. Я лично очень редко, почти никогда не пользуюсь такими ссылками-стрелками если они есть. Попробуйте вспомнить когда вы последний раз кликали на них :-)