Большой архив статей, книг, документации по программированию, вебдизайну, компьютерной графике, сетям, операционным системам и многому другому
 
<Добавить в Избранное>    <Сделать стартовой>    <Реклама на сайте>    <Контакты>
  Главная Документация Новости ИТ Программы Книги Games   Обои   Экспорт RSS E-Books
 
10 новых программ
CodeLobster PHP Edition 3.7.2
WinToFlash 0.7.0008
Free Video to Flash Converter 4.7.24
Total Commander v7.55
aTunes 2.0.1
Process Explorer v12.04
Backup42 v3.0
Predator 2.0.1
FastStone Image Viewer 4.1
Process Lasso 3.70.4
FastStone Image Viewer 4.0
Xion Audio Player 1.0.125
Notepad GNU v.2.2.8.7.7
K-Lite Codec Pack 5.3.0 Full
 
Наши сервисы
Рассылка новостей. Подпишитесь на рассылку сейчас и вы всегда будете в курсе последних событий в мире информационных технологий.
Новостные информеры. Поставьте наши информеры к себе и у вас на сайте появится дополнительный постоянно обновляемый раздел.
Добавление статей. Если вы являетесь автором статьи или обзора на тему ИТ присылайте материал нам, мы с удовольствием опубликуем его у себя на сайте.
 
Поиск по сайту

 
 

  Раздел: Компьютерная документация -> Интернет технологии -> PHP

 

Новый тип навигационной системы при постраничном выводе

Оглавление

Введение

Практически каждый разработчик сталкивался с необходимостью постраничного вывода информации. Каким бы ни был проект, в нем всегда есть "что-то", что не помещается на одну страницу: авторские стихи в маленькой домашней страничке или архив новостей в информационном портале. И каждый раз, когда мы создаем механизм поиска "Первой страницы", "Следующей страницы", "Предыдущей страницы", мы занимаемся рутинной работой. Каждый раз, когда мы в очередной раз переделываем готовую функцию постраничного вывода под новый интерфейс, мы напрасно теряем время. Однако, как правило, попытки создать какую-то единую универсальную функцию постраничного вывода наталкивались на то, что постраничный вывод тесно связан с контекстом. Эту связь можно разделить по степени важности на два уровня:

  • Проблема взаимозависимости контекста и постраничного вывода (основная проблема). Каждый раз, когда мы переходим от одной страницы к другой, мы должны "тащить" за собой огромное количество дополнительных данных, полученных из контекста: например, если мы листаем результаты поиска, то неплохо было бы сохранить параметры поиска при переходах от страницы к странице. Но эта зависимость обоюдная, ведь контекст, в свою очередь, зависит от параметров постраничного вывода: очевидно, что когда мы выбираем просмотр архива новостей за июль, мы будем удивлены, если встретим там новогодние поздравления.

  • Проблема, связанная с организацией внешнего вида (второстепенная проблема). В каждом проекте свой метод вывода информации. Это касается не только внешнего вида постраничных переходов (это может быть кнопка, которая переходит от страницы к странице с помощью метода POST; это может быть ссылка, которая формирует GET-овую строку запроса; и др.), но и способа хранения данных (кнопка или ссылка может формироваться динамически, "на лету"; это может быть шаблон, хранящийся в БД, и др.)

Невозможно создать универсальную систему постраничного вывода (читай: независимую от контекста), если невозможно разделить постраничный вывод и контекст. Причем не заниматься этим "разделением" в каждом проекте, а сделать это один раз, создав универсальную систему, и затем просто использовать ее. Всё это приводит нас к следующему разделу:

Цели и задачи

Целью этой статьи является рассказать об общем методе решения основной проблемы. Это решение неполно, но оно оставлено таким намеренно, чтобы не ограничивать свободы творчества тех разработчиков, которые решат воспользоваться им. Второстепенная проблема практически не затронута, но если идея, реализованная в этой статье, вызовет интерес, то, естественно, мы еще вернемся к этому вопросу.

Однако, прежде, чем начинать обсуждение чего-либо, хотелось бы "сверить часы": объяснить значение терминов, используемых в этой статье, создать своеобразный терминологический словарь:

Словарь терминов

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

  • Постраничный просмотр - способ вывода запрошенной пользователем информации по частям. Каждый постраничный просмотр имеет собственные параметры деления информации на части (например, можно выводить информацию о каждой неделе или о каждом дне текущего месяца). При постраничном просмотре может быть видима информация только одной выбранной части. Эти части называются "страницами".

  • Страница - часть информации, выводимая на при постраничном просмотре, в соответствии с заданными параметрами деления информации на страницы.

  • Навигационная система или система постраничного вывода - это набор кнопок или ссылок, позволяющих пользователю осуществить постраничный просмотр (см. пример ?1).

    Пример 1. Простейшая неграфическая навигационная система
    Первая страница Предыдущая страница 4 5 6 7 8 9 Следующая страница Последняя страница
  • Активная страница - страница, содержимое которой в данный момент просматривает пользователь. В примере ?1 активной является седьмая (7) страница.

  • Навигационная ссылка - кнопка или ссылка (в зависимости от реализации), с помощью которой пользователь может "пролистать" на ту страницу, которая в данный момент не является активной. В примере ?1 страницы 4-6, 8-9, "Первая страница", "Предыдущая страница", "Следующая страница", "Последняя страница" являются навигационными ссылками.

  • Строка в формате md5 - строка, содержащая параметры системы постраничного вывода, однако сформированная таким образом, чтобы внешне походить на md5-строки, генерируемые функцией md5(). См. пример ?2.

Основная идея

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

  1. Количество элементов
  2. Номер активной страницы
  3. Количество навигационных ссылок
  4. Количество элементов на активной странице
Для того, чтобы постраничный вывод был корректным, каждый из этих параметров должен быть целым неотрицательным числом. Именно этот факт натолкнул меня на идею: передавать все параметры постраничного вывода внутри одного, специально отформатированного, параметра. В этой статье мы будем рассматривать упрощенную систему постраничного вывода, в которой отслеживаются только два основных параметра:
  1. Количество элементов
  2. Номер активной страницы

Тому есть 2 причины: во-первых, наши рассуждения могут быть легко распространены на два других параметра; во-вторых, это не будет отвлекать нас в процессе рассуждений.

Теперь изложим нашу идею более подробно для системы постраничного вывода с двумя основными параметрами: поскольку оба параметра - количество элементов и номер активной страницы - являются целыми неотрицательными числами, наиболее оптимальные решением было бы передавать их в виде специально сформированной строки, например, abcd2as15ks2sdm3 (См. пример ?2)

Пример 2. Общий вид специально отформатированной строки,
объединяющей оба основных параметра системы постраничного вывода
abcd 2 as 15 ks 2sdm3
"Маскирующая" часть 1 Номер активной страницы "Разделяющая" часть 2 Общее число элементов "Разделяющая" часть 3 "Маскирующая" часть 4
Необязательная часть. Мы сами определим, как она должна выглядеть. Целое число ≥ 0 Разделитель-"не цифра" (например, буквы латинского алфавита) Целое число ≥ 0 Разделитель-"не цифра" (например, буквы латинского алфавита) Необязательная часть. Мы сами определим, как она должна выглядеть.

Создание строки в формате md5

Итак, давайте подробней обсудим, как будет формироваться наша cтрока в формате md5. Конечно, можно использовать любой другой алгоритм ее формирования, и необязательна эта строка должна быть похожа на md5-строку. И, конечно же, наш способ приведен исключительно в качестве примера. Мы предлагаем формировать строку в формате md5 с учетом следующих условий:

  1. Будем использовать "маскирующую" часть 1 фиксированной длины в 5 символов; для этого сгенерируем с помощью функции md5() строку и будем использовать ее первые 5 символов:

          define('PART1_LENGTH', 5);
          //...
          srand(time());
          $part_1 = substr(md5(uniqid(mt_rand())), 0, PART1_LENGTH);
    
  2. Будем использовать "разделяющую" часть 2 фиксированной длины в 3 символа, который будем случайным образом выбирать из заранее определенной строки $t_str:

          define('PART2_LENGTH', 3);
          //...
          srand(time());
          $t_str = eregi_replace('[0-9]', '', md5(uniqid(mt_rand())));
          $part_2 = substr($t_str, 0, PART2_LENGTH); 
    
  3. Аналогично "разделяющей" части 2, найдем "разделяющую" часть 3:

          define('PART3_LENGTH', 2);
          //...
          srand(time());
          $t_str = eregi_replace('[0-9]', '', md5(uniqid(mt_rand())));
          $part_3 = substr($t_str, 0, PART3_LENGTH); 
    
  4. Теперь совместим все части вместе. Получим результирующую строку вида:

          $res = $part_1.$curindex.$part_2.$total.$part_3;
    
    где
    • $part_1 - "маскирующая" часть 1, полученная на шаге 1;
    • $curindex - номер текущей страницы;
    • $part_2 - "разделяющая" часть 2, полученная на шаге 2;
    • $total - общее число элементов
    • $part_3 - "разделяющая" часть 3, полученная на шаге 3.

  5. Длина нашей строки $res, полученной на шаге 4, может быть меньше, чем 32 символа, и поэтому, поскольку мы создаем строку в формате md5, сгенерируем с помощью функции md5() еще одну, "дополняющую" строку и будем использовать ее для "дополнения" до 32-х символов нашей строки $res. Для этого воспользуемся функцией str_pad():

          define('GENERAL_LENGTH', 32);
          //...
          srand(time());
          $res = str_pad($res, GENERAL_LENGTH, md5(uniqid(mt_rand())), STR_PAD_RIGHT);
    
    где функция str_pad() принимает следующие параметры (более подробно - см. описание функции на сайте http://www.php.net):

    • $res - результирующая строка, полученная на шаге 4;
    • GENERAL_LENGTH - длина строки, которая будет сравниваться с длиной строки $res; если длина строки $res меньше, чем GENERAL_LENGTH, то наша строка $res будет дополнена в соответствии с последующими двумя параметрами до длины GENERAL_LENGTH;
    • md5(uniqid(mt_rand())) - случайным образом сгенерированная строка в формате md5, которая будет использоваться до "дополнения" нашей строки $res до длины GENERAL_LENGTH;
    • STR_PAD_RIGHT - означает, что "дополняющая" строка будет добавляться к нашей строке $res справа.

  6. Оформим формирование строки в формате md5 в виде отдельной функции:

          define('PART1_LENGTH', 5);
          define('PART2_LENGTH', 3);
          define('PART3_LENGTH', 2);
          define('GENERAL_LENGTH', 32);
          
          //...
          
          function makeSecureParam($curindex, $total){
                srand(time());
                $part1 = substr(md5(uniqid(mt_rand())), 0, PART1_LENGTH);
                
                srand(time());
                $t_str = eregi_replace('[0-9]', '', md5(uniqid(mt_rand())));
                $part2 = substr($t_str, 0, PART2_LENGTH); 
          
                srand(time());
                $t_str = eregi_replace('[0-9]', '', md5(uniqid(mt_rand())));
                $part3 = substr($t_str, 0, PART3_LENGTH); 
          
                srand(time());
                return str_pad($part1.$curindex.$part2.$total.$part3, 
                               GENERAL_LENGTH, 
                               md5(uniqid(mt_rand())),  
                               STR_PAD_RIGHT );
          }
    

Итак, основная идея нами реализована : мы создали функцию, позволяющую "прятать" параметры системы постраничного вывода внутрь одной, специального вида строки. Какие преимущества нам это дает? Поскольку теперь наша система постраничного вывода характеризуется всего одним параметром, то это даст нам возможность встраивать систему постраничного вывода в контекст, а не наоборот, как это было раньше. Осталось только реализовать класс, который позволил бы принимать эту специального вида строку и преобразовывать ее в соответствующие параметры навигационной системы.

Описание класса

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

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

  1. Класс содержит две переменных: общее число элементов и номер активной страницы.

          class navigation{
                var $curpage; /* active page number */
                var $total; /* total items */
                
                //...
          }
    
  2. Конструктор класса инициализирует "пустой" набор элементов (это предоставит возможность инициализировать экземпляр класса несколько раз):

          class navigation{
                //...
          
                function navigation(){
                      $this->curpage = $this->total = 0;
                }
          }
    
  3. Прежде, чем анализировать заданную строку в формате md5, исключим из нее "маскирующую" часть 1:

          $str = substr($str, PART1_LENGTH);
    
  4. Проанализируем заданную строку в формате md5 с помощью функции preg_split() (более подробно - см. описание функции на сайте http://www.php.net):

          preg_split('/[^0-9]/si', $str, 3, PREG_SPLIT_NO_EMPTY)
    
    где
    • '/[^0-9]/si' - образец, позволяющий выделить из строки $str те ее части, которые состоят только из цифр; например, если
            $str = 'cf16b2bcf12fd72dc05154e87749d940'
      то результатом выполнения функции
            preg_split('/[^0-9]/si', $str)
      будет массив значений:

      • 16
      • 2
      • 12
      • 72
      • 05154
      • 87749
      • 940

    • $str - заданная строка в формате md5;

    • 3 - специальный параметр функции preg_split(), которая говорит, что нужно анализировать только первых три (3) совпадения в заданной строке $str;например, если
            $str = 'cf16b2bcf12fd72dc05154e87749d940'
      то результатом выполнения функции
            preg_split('/[^0-9]/si', $str, 3)
      будет массив значений:

      • 16
      • 2
      • cf12fd72dc05154e87749d940

    • PREG_SPLIT_NO_EMPTY - специальный параметр, который позволяет выводить только непустые строки, которые соответствуют заданному шаблону поиска.

  5. Поскольку функция preg_split() возвращает в качестве результата массив значений, то наиболее удобно использовать функцию list() обработки результатов - запишем первое полученное число во временную переменную $curpage, а второе - во временную переменную $total (этот порядок определяется способом формирования строки в формате md5 с помощью функции "makeSecureParam"):

          @list($curpage, $total) = preg_split('/[^0-9]/si', $str, 3, PREG_SPLIT_NO_EMPTY);
    
  6. Чтобы исключить всевозможные "неожиданности", преобразуем полученные результаты к целым неотрицательным числам, а результат запишем в соответствующие переменные нашего класса:

          $this->curpage = abs(intval($curpage));
          $this->total = abs(intval($total));
    
  7. Оформим анализ строки в формате md5 в виде функции init, которая позволит выделить из данной строки необходимые параметры навигационной системы: общее число элементов и номер активной страницы.

    define('PART1_LENGTH', 5);
    
    //...
    
    class navigation{
    
          //...
    
          function init($str = ''){
                $str = substr($str, PART1_LENGTH);
          
                if (!trim($str)){
                      $this->curpage = $this->total = 0;
                      return;
                }
                      
                @list($curpage, $total) = preg_split('/[^0-9]/si', 
                                                     $str, 3, PREG_SPLIT_NO_EMPTY);
                $this->curpage = abs(intval($curpage));
                $this->total = abs(intval($total));
          }
    }
    

Итоги

Статья может быть полезной любому человеку, знакомому с синтаксисом РНР и владеющему по крайней мере начальным опытом программирования на РНР. В этой статье нет готовых рецептов. В ней изложен метод решения, которым каждый может воспользоваться. Главной идеей является "сокрытие" всех параметров навигационной системой внутри одной строки специального формата (в приведенном примере используется формат "а-ля md5" :) ). Представлена функция, формирующая строку в формате md5, и базовый класс, позволяющий инициализировать параметры навигационной системы по заданной строке в формате md5. Преимущества данного метода:

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

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

Автор: Felenka
Источник: www.providerz.ru



  Добавить закладку на материал: 


Ссылки по теме
Внутренние функции
Обработка строк в РНР
PHP и всё такое...
Пишем PHP код, устойчивый к ошибкам
Полезные скрипты на PHP
Почтовые функции в РНР
Полезные функции для работы с файловой системой

Вся документация PHP

 

Компьютерная документация от А до Я - Главная

 
 


 

загрузка...

Новости ИТ
17.05.2012  Zalman планирует представить на Computex пять процессорных кулеров серии CNPS
17.05.2012  Virgin Mobile USA начала продажи смартфона LG Optimus Elite
17.05.2012  ROCCAT начала продажи бюджетной игровой мышки Savu
17.05.2012  Securify анонсировала выпуск в США Wi-Fi маршрутизатора Almond с цветным тачскрином
17.05.2012  Названа цена смартфона LG Optimus LTE II с 2 ГБ оперативной памяти
17.05.2012  Sony анонсировала поставки камеры SLT-A37 и объектива SAL18135
17.05.2012  Стали известны спецификации и цена процессора Intel Core i5-3210M
17.05.2012  В Сети появились концептуальные изображения Apple iPhone 5
17.05.2012  Мышь Razer Ouroboros «засветилась» на сайте FCC
17.05.2012  Sony анонсировала выпуск объектива SEL18200LE E18-200mm F3.5-6.3 OSS LE
17.05.2012  Беспроводной маршрутизатор PROLiNK WNR1012 может играть роль мобильной точки доступа
17.05.2012  Внешний оптический привод Buffalo BRXL-PC6VU2 поддерживает чтение и запись дисков BDXL
17.05.2012  Представлена беззеркальная камера начального уровня Sony NEX-F3
17.05.2012  Galaxy выпускает видеокарты серии GeForce GT 600, включая модель GeForce GT 610 с пассивным охлаждением
17.05.2012  QNAP представляет свои первые шестнадцатидисковые сетевые хранилища
17.05.2012  NVIDIA представила первый в мире виртуализированный GPU для ускорения облачной графики
17.05.2012  Для снижения цены кулера Alpenfцhn Matterhorn Pure Edition производитель отказался от никелирования
17.05.2012  По подсчетам Gartner, продажи сотовых телефонов уменьшились на 2%, лидером рынка является Samsung
17.05.2012  ADATA начинает продажи двухканальных наборов модулей памяти XPG Xtreme DDR3-2133X
17.05.2012  Портативный монитор PROLiNK PRO1301WE питается от порта USB
16.05.2012  AOC начала продажи 22-дюймового LED-монитора e2219P2
16.05.2012  Palit представила три видеокарты моделей GeForce GT 630, GeForce GT 620 и GeForce GT 610
16.05.2012  Смартфон LG Optimus 4X HD появится в Европе уже в июне
16.05.2012  Lenovo планирует вывести на рынок суперлегкий ультрабук ThinkPad X1 Carbon
16.05.2012  Toshiba уже в этом месяце начнет продажи в Японии четырех планшетников линейки Regza
16.05.2012  Xilence Technology начала продажи 750-Вт и 850-Вт блоков питания серии XQ
16.05.2012  Zotac готовит к выходу высококачественную и производительную видеокарту модели GeForce GTX 670 Extreme
16.05.2012  Google готовит пять смартфонов Nexus?
16.05.2012  Nokia показала двухсимные телефоны для развивающихся стран
16.05.2012  AMD анонсировала второе поколение APU Trinity

 
Advertisment



 
Интересное в сети

Copyright © CompDoc.Ru
При цитировании и перепечатке ссылка на www.compdoc.ru обязательна. Карта сайта.
 
Rambler's Top100