Панель навигации на php

Постраничная навигация на PHP

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

Существует множество вариаций расположения и отображения кнопок, лично я пришел к следующему решению, которое по моему мнению наиболее наглядно и удобно. Подходит как для 5 страниц так и для 5000.

Пример HTML кода

Не буду ходить вокруг да около, сразу приложу пример сформированного скриптом html кода:

 
Назад 1 . 4 5 6 7 8 9 10 . 17 Вперед

Логика построения

По настройкам параметров я остановлюсь чуть позже после приведения кода, сейчас опишу логику формирования самих номеров.

С кнопками «Назад» и «Вперед» думаю все понятно, к тому же их можно просто отключить, поэтому на них не буду заострять внимания.

Первый и последний номер страницы отображается всегда, своего рода кнопки «В начало» и «В конец».

Середина формируется уже по простому алгоритму. Отображается просматриваемая страница и по N страниц по бокам. На примере отображается по N=3 страницы. В принципе все просто и понятно, но особая хитрость используется при приближении к краям. Опишу на примерах:

Страница 1-3 (где 3 = N)

Отображаются первые N*2 страниц и последняя.

Отображается первая и дальше сформированная строка от 4-3=1 до 4+3=7. Первая страница зарезервирована поэтому формируются номера от 2 до 7.

Пожалуй во всех навигациях что я видел (включая хабр) строка была бы сформирована с пропуском, т.е. 1… 3 4 5 6 7 8 9… 17
Но ведь это не логично, отображать многоточие вместо одного числа. При построении второго многоточия выполняется аналогичная проверка.

Формирование окончания аналогично началу

Редиректы

Помимо этого из особенностей хочу выделить еще 2 момента, это проверка существования страницы и редирект на «правильный» адрес. Т.е. к примеру, тут же на хабре первая страница может быть доступна сразу по 2м адресам:
habrahabr.ru/sandbox/page1
habrahabr.ru/sandbox

Скрипт не дает зайти на адрес page/1/ и выполняет редирект на «чистый» адрес
Так же если указан слишком большой номер страницы будет выполнен редирект на последнюю существующую. К примеру были удалены материалы или изменено количество записей на страницу. Не могу правда однозначно сказать полезно ли это будет с точки зрения СЕО, но для пользователей мне кажется так будет удобнее.

PHP код и его использование

class PaginateNavigationBuilder < /** * Чистый URL по умолчанию * В адресе может быть указано место для размещения блока с номером страницы, тег * Пример: * /some_url.html * В итоге адрес будет: * /some_url.html * /some_url/page_2.html * Если тег не указан, то страницы будут дописываться в конец адреса * * @var string */ private $baseUrl = '/'; /** * Шаблон ссылки навигации * * @var string */ public $tpl = 'page//'; /** * Обертка кнопок * * @var string */ public $wrap = "baseUrl = $baseUrl; > /** * Строим навигации и формируем шаблон * * @param integer $limit количество записей на 1 страницу * @param integer $count_all общее количество всех записей * @param integer $currentPage номер просматриваемой страницы * @return mixed Сформированный шаблон навигации готовый к выводу */ public function build($limit, $count_all, $currentPage = 1) < if( $limit < 1 OR $count_all $count_pages ) < header( "HTTP/1.0 301 Moved Permanently" ); header( "Location: " . $this->getUrl( $count_pages ) ); die( "Redirect" ); > if( $currentPage == 1 AND $_SERVER['REQUEST_URI'] != $this->getUrl( $currentPage ) ) < header( "HTTP/1.0 301 Moved Permanently" ); header( "Location: " . $this->getUrl( $currentPage ) ); die( "Redirect" ); > $this->currentPage = intval( $currentPage ); if( $this->currentPage < 1 ) $this->currentPage = 1; $shift_start = max( $this->currentPage - $this->spread, 2 ); $shift_end = min( $this->currentPage + $this->spread, $count_pages-1 ); if( $shift_end < $this->spread*2 ) < $shift_end = min( $this->spread*2, $count_pages-1 ); > if( $shift_end == $count_pages - 1 AND $shift_start > 3 ) < $shift_start = max( 3, min( $count_pages - $this->spread*2 + 1, $shift_start ) ); > $list = $this->getItem( 1 ); if ($shift_start == 3) < $list .= $this->getItem( 2 ); > elseif ( $shift_start > 3 ) < $list .= $this->separator; > for( $i = $shift_start; $i getItem( $i ); > $last_page = $count_pages - 1; if( $shift_end == $last_page-1 )< $list .= $this->getItem( $last_page ); > elseif( $shift_end < $last_page ) < $list .= $this->separator; > $list .= $this->getItem( $count_pages ); if( $this->nextPrev ) < $list = $this->getItem( $this->currentPage > 1 ? $this->currentPage - 1 : 1, $this->prevTitle, true ) . $list . $this->getItem( $this->currentPage < $count_pages ? $this->currentPage + 1 : $count_pages, $this->nextTitle, true ); > return str_replace( "", $list, $this->wrap ); > /** * Формирование адреса * @param int $page_num номер страницы * @return string сформированный адрес */ private function getUrl( $page_num = 0 ) < $page = $page_num >1 ? str_replace( '', $page_num, $this->tpl ) : ''; if( stripos( $this->baseUrl, '' ) !== false )< return str_replace( '', $page, $this->baseUrl ); > else < return $this->baseUrl . $page; > > /** * Формирование кнопки/ссылки * @param int $page_num номер страницы * @param string $page_name если указано, будет выводиться текст вместо номера страницы * @param bool $noclass * @return - span блок с активной страницей или ссылку. */ private function getItem( $page_num, $page_name = '', $noclass = false ) < $page_name = $page_name ?: $page_num; $className = $noclass ? '' : $this->activeClass; if( $this->currentPage == $page_num ) < return "else < return "getUrl($page_num)>\"> "; > > >

Для наглядности, приведу пример построения навигации песочницы:
habrahabr.ru/sandbox/page12

$navi = new PaginateNavigationBuilder( "/sandbox/" ); $navi->tpl = "page/"; $navi->spread = 4; $template = $navi->build( $limit, $count_all, $page_num );

Или же если номер страницы прописан внутри URL:
example.com/some_url/1.html — первая страница
example.com/some_url/1-page2.html — вторая страница

$navi = new PaginateNavigationBuilder( "/some_url/1.html" ); $navi->tpl = "-page"; $template = $navi->build( $limit, $count_all, $page_num );

$limit — количество записей на страницу
$count_all — общее количество записей
$page_num — номер страницы на которой находится пользователь

Читайте также:  Python sleep до определенного времени

На этом, пожалуй, всё. Буду рад любой конструктивной критике.

PS. Огромное спасибо всем отписавшимся, особенно тем кто ругает (и правильно делает).
Обещаю со всем ознакомиться, принять во внимание и исправиться.

Источник

Навигация по страницам на PHP

Если у Вас динамический сайт, то, наверняка, Вам потребуется сделать навигацию по страницам. Допустим, если у Вас блог и у Вас есть хотя бы 50 записей, то согласитесь, что на одной странице Вы их все не выведите. Такая страница будет огромной и бестолковой. И в этой статье я расскажу, как сделать навигацию по страницам на PHP.

В основе лежат оператор LIMIT и GET-параметр. Вот примерный алгоритм работы:

  1. Получить значение GET-параметра, отвечающего за номер страницы.
  2. На основании значения переданного номера страницы, вывести из базы данных только те записи, которые должны находиться на этой странице.
  3. Вывести получившиеся записи на страницу.

Чтобы стало понятнее, давайте приведу стандартный код шаблона, который реализует подобный алгоритм:

$count = 5;// Количество записей на странице
$page = $_GET[«page»];// Узнаём номер страницы
$mysqli = new mysqli(«localhost», «root», «», «db»);// Подключаемся к базе данных
$shift = $count * ($page — 1);// Смещение в LIMIT. Те записи, порядковый номер которого больше этого числа, будут выводиться.
$result_set = $mysqli->query(«SELECT * FROM `articles` LIMIT $shift, $count»);// Делаем выборку $count записей, начиная с $shift + 1.
/* Выводим результат */
while ($row = $result_set->fetch_assoc()) print_r($row);
echo «
«;
>
?>

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

Читайте также:  Java print map as string

Создано 30.01.2012 14:54:28

  • Михаил Русаков
  • Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!

    Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
    Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.

    Если Вы не хотите пропустить новые материалы на сайте,
    то Вы можете подписаться на обновления: Подписаться на обновления

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

    Порекомендуйте эту статью друзьям:

    Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

    1. Кнопка:
      Она выглядит вот так:
    2. Текстовая ссылка:
      Она выглядит вот так: Как создать свой сайт
    3. BB-код ссылки для форумов (например, можете поставить её в подписи):

    Комментарии ( 38 ):

    А как можно реализовать номера страниц как на картинке в шапке темы?

    Можно, здесь принцип простой: выводить просто ссылки: 5. Вместо 5 вывести в цикле все необходимые страницы. Но здесь простая база, но если хочется делать какой-то сдвиг (допустим, на 1-й странице, можно перейти с 1-й по 10-ю страницу, а на 10 страницы, например, с 5-й по 15-ю), то здесь уже всё гораздо сложнее, и в двух строчках никак не опишешь. Тут надо просто сесть и подумать.

    Я вот все сделал, но у меня выводит так: Array ( [id] => 1 [theme] => test [newa] => text text text [newb] => text1 text1 text [user] => user [cat] => 3 ) Почему выводит название полей и т.д?

    Правильно всё выводит, далее нужно этот массив обрабатывать и выводить данные так, как того требует Ваш дизайн и вёрстка. Они у каждого уникальны.

    А как именно их можно обработать? Можно пример, а то я их ранее не разу не обрабатывал.

    Почитайте про работу с массивами в PHP. Затем внутрь HTML просто в нужные места подставляйте все данные из массива.

    Читайте также:  Php file put contents fwrite

    «Можно, здесь принцип простой: выводить просто ссылки: 5. Вместо 5 вывести в цикле все необходимые страницы.» Здравствуйте, Михаил! А можно пример. А то я не совсем понял.

    Источник

    Постраничная навигация на PHP

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

    Приступим?

    Первое, что нам нужно для этого иметь – это базу данных с несколькими десятками строк, например статей или комментариев к ним (что угодно). Мы будем рассматривать базу данных MySQL, она является самой популярной на данный момент. Естественно используемый язык – это PHP.

    1. Создаём для примера файл primer.php;
    2. Создаём Базу данных primer (можете не создавать, если у вас уже есть подходящая);
    3. Создаём таблицу primer вот такой структуры (опять же, если нет другой);

    CREATE table primer ( id int auto_increment primary key key, name varchar(100) NOT NULL, text longtext NOT NULL );

    4. Набиваем её информацией. Я сделаю 20 записей, мне не день 😉
    5. Набираемся терпения – сейчас будем кодить.

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

    Запихиваем нижележаций код в primer.php и пытаемся понять как же он работает:

    Ошибочка вышла!'; // СОЕДЕНИМСЯ С MySQL $connect = mysql_connect ($server, $user, $pass); if (!$connect) < echo $text_error; exit; >// СОЕДЕНИЯЕМСЯ С БАЗОЙ ДАННЫХ $select = mysql_select_db($db); if (!$select) < echo $text_error; exit; >// СОЗДАЁМ ЗАПРОС $result = mysql_query("SELECT * from $table ORDER by id desc"); // СЧИТАЕМ КОЛЛИЧЕСТВО ЗАПИСЕЙ В ТАБЛИЦЕ - У МЕНЯ ИХ 20 $num_rows = mysql_num_rows($result); // А ТЕПЕРЬ СЧИТАЕМ НА СКОЛЬКО СТРАНИЦ НАМ РАЗБИТЬ ЗАПИСИ И ВЫДЕЛЯЕМ ЦЕЛОЕ ЧИСЛО $num_rows = round($num_rows/$chislo); // 20 ДЕЛИМ НА 5. СКОЛЬКО? :) // ЗДЕСЬ МЫ ПРОВЕРЯЕМ НА КАКОЙ СТРАНИЦЕ СЕЙЧАС ПОЛЬЗОВАТЕЛЬ if (isset($_GET['str'])) < $nav = $_GET['str']; >else < $nav = 0; >$nav = intval($nav); // ДЛЯ ЗАЩИТЫ ОТ НЕХОРОШИХ ДЯДЕНЕК МЫ ВЫДЕЛИМ ЦЕЛУЮ ЧАСТЬ $GET['str'] echo 'Навигация: '; // А ТЕПЕРЬ ВЫВОДИМ НОМЕРА СТРАНЦ for ($i=1; $i'.$i.' '; > else < // АКТИВНУЮ СТРАНИЦУ ДЕЛАЕМ НЕ ГИПЕРССЫЛКОЙ echo ''.$i.' '; > > echo '
    '; // ОТДЕЛИМ НАВИГАЦЮ ОТ КОНТЕНТА ДЛЯ НАГЛЯДНОСТИ // НАЧИНАЕМ ВЫВОДИТЬ САМУ ИНФОРМАЦИЮ ПОСТРАНИЧНО :) if (!isset($_GET['str'])) < $str = 0; >else < $str = $_GET['str']*$chislo - $chislo; >$nomer = $str + 5; // ФОРМИРУЕМ ЗАПРОС НУЖНОЙ НАМ ЧАСТИ ИНФОРМАЦИИ $result = mysql_query("SELECT * from $table ORDER by id asc limit $str, $nomer"); // ИНАЧЕ ВЫВОДИМ ОШИБКУ if (!$result) < echo $text_error; exit; >echo '
    '; while ($row = mysql_fetch_array($result)) < echo '

    '.$row['id'].' - '.$row['name'].'
    '.substr($row['text'],0,100).'.. >>

    '; > echo '
    '; mysql_close($connect); ?>

    Поясню лишь, что в переменной «str» передаётся номер страницы, на которой находится пользователь, в адрессной строке браузера это выглядит так:

    Вот и всё, скрипт постраничного вывода у нас готов! Примерно, это должно выглядеть так:

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

    Источник

    Оцените статью