За последние 24 часа нас посетили 22606 программистов и 1218 роботов. Сейчас ищут 729 программистов ...

Постраничный вывод результатов (он же пейджер)

Тема в разделе "PHP для новичков", создана пользователем 440Hz, 16 авг 2007.

  1. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    от поиска перебором по тексту в любом случае надо уходить.
    а в данном случае SELECT COUNT(*) будет уместен.
     
  2. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    > Рисовать ссылки `назад` и `вперед`, поиск все-таки а не просмотр рейтингов.

    более того, такой схемы достаточно для 99% возможных применений пейджэра :)
     
  3. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    > CI, кодировки, латиница/кирилица - в одно время меня достали, и больше ничем кроме `пустого` REGEXP не пользуюсь.

    индексы тебя тоже, я смотрю, достали? :)
     
  4. DZEN

    DZEN Активный пользователь

    С нами с:
    10 сен 2007
    Сообщения:
    250
    Симпатии:
    0
    Это не мне объясняй, а богатому дяде который видел что "На Яндексе после поиска все страницы видны".

    На все индексы не повесишь. А меня вообще жизнь достала :), сейчас еще триггеры сяду писать на mysql - запомните меня добрым и веселым :twisted:.

    Не уходите от темы постраничного вывода!
     
  5. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    приведи контакты богатого дяди - буду объяснять.
     
  6. DZEN

    DZEN Активный пользователь

    С нами с:
    10 сен 2007
    Сообщения:
    250
    Симпатии:
    0
    Айм сорри, бат айм токин ту ю фром Юкрэйн :).
    А так бы с удовольствим - делись и тебе поделят...
     
  7. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    на юкрэйн не провэли энтэрнэт?
     
  8. DZEN

    DZEN Активный пользователь

    С нами с:
    10 сен 2007
    Сообщения:
    250
    Симпатии:
    0
    Лично высеку тебе памятник если ты мне здесь найдешь заказчика который будет работать с другой страной, если есть возможность вживую пообщаться с местными фирмами. Кстати энтэрнэт у нас тут 4 мб у каждого третьего, а если у вас на форуме с этим такие серьезные психологические проблемы - я русский. Мне пофиг, могу и на англоязычных форумах посидеть (ёж птица гордая, не пнешь - не полетит :p ).
     
  9. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    Sergey89 выложи свое решение, плизз.
     
  10. creage

    creage Активный пользователь

    С нами с:
    12 мар 2008
    Сообщения:
    131
    Симпатии:
    0
    Адрес:
    Киев
    писал года 2 назад

    PHP:
    1. <?php
    2. Class Scroller {
    3.  
    4.     public $itemsCount = 0,
    5.     $limit,
    6.     $pageCount,
    7.     $currentPage,
    8.     $currentPageNumber,
    9.     $currentPageName,
    10.     $offset,
    11.     $direction,
    12.     $firstPage,
    13.     $lastPage,
    14.     $formName;
    15.  
    16.     function Scroller($itemsCount, $itemsPerPage, $formName, $direction, $page = 0){
    17.         $this->formName = empty($formName) ? "page" : $formName;
    18.         $this->page = empty($page) ? $_REQUEST[$this->formName] : $page;
    19.         $this->itemsCount = (int)$itemsCount;
    20.         $this->limit = (int)$itemsPerPage;
    21.         $this->pageCount = ceil($this->itemsCount / $this->limit);
    22.         if((int)$direction < 0){
    23.             $this->currentPage = !(int)$this->page && $this->page != "0" ? $this->pageCount : $this->page;
    24.             if($this->currentPage > $this->pageCount){
    25.                 $this->currentPage = $this->pageCount;
    26.             } else {
    27.                 if($this->currentPage < 1) $this->currentPage = 1;
    28.             }
    29.             $this->currentPageNumber = $this->pageCount - $this->currentPage + 1;
    30.             $this->currentPageName = $this->currentPageNumber;
    31.             if($this->pageCount && $this->currentPage < $this->pageCount){
    32.                 $this->isFullPage = $this->itemsCount % $this->limit ? 1 : 0;
    33.                 $this->offset = $this->itemsCount % $this->limit + ($this->pageCount - $this->currentPage - $this->isFullPage) * $this->limit;
    34.             } else {
    35.                 $this->offset = 0;
    36.             }
    37.             $this->direction = "-1";
    38.             $this->firstPage = $this->pageCount;
    39.             $this->lastPage = 1;
    40.         } else {
    41.             $this->currentPage = !(int)$this->page && $this->page != "0" ? 1 : $this->page;
    42.             if($this->currentPage > $this->pageCount){
    43.                 $this->currentPage = $this->pageCount;
    44.             } else {
    45.                 if($this->currentPage < 1) $this->currentPage = 1;
    46.             }
    47.             $this->currentPageNumber = $this->currentPage;
    48.             $this->currentPageName = $this->currentPage;
    49.             $this->direction = "+1";
    50.             $this->firstPage = 1;
    51.             $this->lastPage = $this->pageCount;
    52.             $this->offset = $this->pageCount ? ($this->currentPage - 1) * $this->limit : 0;
    53.         }
    54.     }
    55.  
    56.     function show($params = 0){
    57.         $sReturn = "";
    58.         if($this->pageCount >1){
    59.             if(isset($params["mode"])) $this->mode = $params["mode"];
    60.             $this->navCount = (int)$params["navCount"] ? $params["navCount"] : 5;
    61.             $this->firstNav = $this->currentPageNumber - floor($this->navCount / 2);
    62.             if($this->firstNav < 1) $this->firstNav = 1;
    63.             $this->lastNav = $this->firstNav + $this->navCount - 1;
    64.             if($this->lastNav > $this->pageCount){
    65.                 $this->lastNav = $this->pageCount;
    66.                 $this->firstNav = $this->lastNav - $this->navCount;
    67.                 if($this->firstNav < 1) $this->firstNav = 1;
    68.             }
    69.             $this->separator = isset($params["separator"]) ? $params["separator"] : "&hellip;";
    70.             $qupos = strpos($params["targetUrl"], "?");
    71.             $this->urlSeparator = $qupos !== false ? "&" : "?";
    72.             if(isset($params["tagName"])) $sReturn .= "<" . $params["tagName"] . " " . $params["tagAttr"] . " >";
    73.             $this->title = isset($params["title"]) ? $params["title"] : "Страницы: ";
    74.             if($this->mode == "html"){
    75.                 $sReturn .= $this->title;
    76.             } else {
    77.                 $sReturn = "<title>" . $this->title . "</title>";
    78.                 if(isset($params["leftDivider"])) $sReturn .= "<left-divider>" . $params["leftDivider"] . "</left-divider>";
    79.                 if(isset($params["rightDivider"])) $sReturn .= "<right-divider>" . $params["rightDivider"] . "</right-divider>";
    80.             }
    81.             if($this->currentPage != $this->firstPage){
    82.                 $backName = isset($params["backName"]) ? $params["backName"] : "&larr; Назад";
    83.                 $sReturn .= $this->_printNavItem("back", $backName, $params["targetUrl"], $this->urlSeparator, $this->currentPage - $this->direction);
    84.                 if($this->mode == "html" && isset($params["leftDivider"])) $sReturn .= $params["leftDivider"];
    85.             }
    86.             if($this->firstNav > 1){
    87.                 $sReturn .= $this->_printNavItem("first", 1, $params["targetUrl"], $this->urlSeparator, $this->firstPage);
    88.                 if($this->firstNav > 2) $sReturn .= $this->_printNavItem("separator", $this->separator);
    89.             }
    90.             for ($i = $this->firstNav; $i <= $this->lastNav; $i++) {
    91.             $current = "";
    92.             $ipage = $this->direction < 0 ? $this->pageCount - $i + 1 : $i;
    93.             if($ipage == $this->currentPage) $current = "current";
    94.             $sReturn .= $this->_printNavItem($current, $i, $params["targetUrl"], $this->urlSeparator, $ipage);
    95.             }
    96.             if($this->lastNav < $this->pageCount){
    97.                 if($this->lastNav < $this->pageCount - 1) $sReturn .= $this->_printNavItem("separator", $this->separator);
    98.                 $sReturn .= $this->_printNavItem("last", $this->pageCount, $params["targetUrl"], $this->urlSeparator, $this->lastPage);
    99.             }
    100.             if($this->currentPage != $this->lastPage){
    101.                 if($this->mode == "html"){
    102.                     $sReturn .= isset($params["rightDivider"]) ? $params["rightDivider"] : "|";
    103.                 }
    104.                 $forwardName = isset($params["forwardName"]) ? $params["forwardName"] : "Дальше&nbsp;&rarr;";
    105.                 $sReturn .= $this->_printNavItem("forward", $forwardName, $params["targetUrl"], $this->urlSeparator, $this->currentPage + $this->direction);
    106.             }
    107.             if(isset($params["tagName"])) $sReturn .= "</" . $params["tagName"] . " >";
    108.         }
    109.         return $sReturn;
    110.     }
    111.  
    112.     function _printNavItem($type, $name, $url = "", $urlSeparator = "", $pageNum = ""){
    113.         $sReturn = "";
    114.         if($this->mode == "html"){
    115.             if($type == "separator"){
    116.                 $sReturn = "\n<span class=\"separator\">".$name."</span>\n";
    117.             } elseif($type != "current" && (int)$pageNum) {
    118.                 $sReturn .= "\n<a href=\"";
    119.                 $sReturn .= !empty($url) ? $url : "./";
    120.                 if($pageNum != $this->firstPage) $sReturn .= $urlSeparator.$this->formName."=".$pageNum;
    121.                 $sReturn .= "\"";
    122.                 if(empty($type) || $type == "first" || $type == "last") $sReturn .= " class=\"scrollerPage\"";
    123.                 $sReturn .= ">".$name."</a>\n";
    124.             } else {
    125.                 $sReturn = "\n<span class=\"scrollerCurrentPage\">".$name."</span>\n";
    126.             }
    127.         } else {
    128.             $sReturn = "<page ";
    129.             if(isset($type)) $sReturn .= 'type="'.$type.'" ';
    130.             if($type != "current" && !empty($pageNum)){
    131.                 $sReturn .= 'href="';
    132.                 !empty($url) ? $sReturn .= $url : $sReturn .= "./";
    133.                 if($pageNum != $this->firstPage) $sReturn .= $urlSeparator.$this->formName.'='.$pageNum;
    134.                 $sReturn .= '" num="'.$name.'" ';
    135.             }
    136.             $sReturn .= "/>";
    137.         }
    138.         return $sReturn;
    139.     }
    140. }
    141.  
    142. ?>
    примерный вызов

    PHP:
    1.  
    2. <?php
    3.     // default params
    4.     $aParams = array(
    5.         "lang_id" => $oSiteCurrentLanguage->id,
    6.         "group_id" => $aCurrentSection['groupID'],
    7.         "is_active" => 1
    8.     );
    9.     // get articles count
    10.     $rowCount = Article::get($aParams + array("count" => true));
    11.     // init scroller
    12.     $oScroller = new Scroller($rowCount, 10, 'page', 1);
    13.     // scroller params
    14.     $hScrollerParams = array(
    15.         "targetUrl" => getScrollerPath('page'),
    16.         "navCount" => 5,
    17.         "mode" => "html",
    18.         "title" => "##Pages##: ",
    19.         "backName" => "##PreviousPage##",
    20.         "forwardName" => "##NextPage##"
    21.     );
    22.  
    23.     echo $oScroller->show($hScrollerParams);
    24.     $articles = Article::get($aParams + array(
    25.         "limit" => $oScroller->limit,
    26.         "offset" => $oScroller->offset
    27.     ));
    28. ?>
     
  11. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    аап!
    И еще: почему все делают нумерацию страниц новостей 1 2 3 ... а не ... 3 2 1 ? Ведь самый новый, по идее, контент располагается на первой странице. Ну гляньте как это на Хабрахабре и на любом сайте, построенном на DLE, думаю поймете, о чем я.

    upd: ну не все, а почти все)
     
  12. topas

    topas Активный пользователь

    С нами с:
    16 авг 2006
    Сообщения:
    2.258
    Симпатии:
    36
    Неправда, у 440Hz я видел именно такую нумерацию

    Поправьте меня, если ошибаюсь
     
  13. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    У тебя дни тоже в обратном порядке считаются? Месяц с какого числа начинаешь? 30?
     
  14. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    Kreker
    знаешь хоотя б одно очень важное преимущество такого способа?

    1) Контент не будет "плавающим" по страницам. Если он на 3 странице, то и с добавлением 100 новостей так и останется на 3 странице, а не "уползет" на 13-ю.

    секундочку, а почему же тогда мы начинаем вывод с последней новости, а не с первой?
     
  15. topas

    topas Активный пользователь

    С нами с:
    16 авг 2006
    Сообщения:
    2.258
    Симпатии:
    36
    Koc
    Полностью с вами согласен, осталось только придумать как решить задачу:
    сегодня /news/ отображает вторую страницу,
    завтра - третью
     
  16. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    Дайте мне точку опоры. А именно пейджер от Sergey89, мне он больше всех понравился). И будем копать.
     
  17. creage

    creage Активный пользователь

    С нами с:
    12 мар 2008
    Сообщения:
    131
    Симпатии:
    0
    Адрес:
    Киев
    в моем коде это уже решено) просто передаете направление скроллера
    PHP:
    1. function Scroller($itemsCount, $itemsPerPage, $formName, $direction, $page = 0)
    параметр дайрекшн. если 1, то нумерация с конца, если -1, то с начала.

     
  18. topas

    topas Активный пользователь

    С нами с:
    16 авг 2006
    Сообщения:
    2.258
    Симпатии:
    36
    creage
    Спасибо за пример.
     
  19. joost

    joost Guest

    Вот мой вариант
    PHP:
    1.  
    2. function page($all_data, $str, $po_kilk_str, $po_kilk_data)
    3. {
    4. $url="http://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
    5.  
    6. $url=preg_replace("/\&str=(\d+)/isU", "", $url);
    7.  
    8. $kilk_str=ceil($all_data/$po_kilk_data);
    9.  
    10.  
    11. $begin=$str-$po_kilk_str/2;
    12. $end=$str+$po_kilk_str/2;
    13.  
    14. if ($kilk_str<=$po_kilk_str)
    15.     {
    16.     $begin=1;
    17.     $end=$kilk_str;
    18.     }
    19. else
    20.     {
    21.     if ($begin<=0) {$begin=1;}
    22.     if ($str<$po_kilk_str/2) { $end=$po_kilk_str;}
    23.     if ($str+$po_kilk_str/2>$kilk_str) {$end=$kilk_str; $begin=$kilk_str-$po_kilk_str;}
    24.     }
    25.  
    26. print "<table width=100%>\n";
    27. print "<tr><td>";
    28.  
    29.  
    30. for ($i=$begin;$i<=$end;$i++)
    31. {
    32.     if ($str==$i) {$b_begin="<b>";$b_end="</b>";} else {$b_begin="";$b_end="";}
    33. print " <a href=$url&str=$i>$b_begin$i$b_end</a> ";
    34. }
    35. print "</td></tr>";
    36. print "</table>\n";
    37. }
    38. page($all_data, $str, $po_kilk_str, $po_kilk_data);
    39.  
    $all_data - всего записей
    $str - текущая страница
    $po_kilk_str - по сколько ссылок на страници показывать
    $po_kilk_data - по сколько записей выводить

    Прошу сильно не критиковать!
     
  20. MrVOVA

    MrVOVA Активный пользователь

    С нами с:
    14 июн 2008
    Сообщения:
    31
    Симпатии:
    0
    ти на 100% прав! я новичок и нечиво непонял!
     
  21. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.340
    Симпатии:
    44
    Угу, и 21-я новость при 20 элементах на странице будет висеть одинеханька. Очень красиво.
    Эта писец, не подпускайте программистов к проектированию интерфейсов, одному "вперед - назад" достаточно, другой газеты с конца читает. Жжж...
     
  22. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    Камрад, зайди на Хабрахабр.
     
  23. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.340
    Симпатии:
    44
    И? Там, по-вашему, новости не уезжают со своих номеров страниц? Проверьте ;)
    А то, что они нумеруются назад - никакого облегчения никому не приносит. Читаем мы с первой страницы до последней и с новейшей новости до старейшей - так уж приучены, - отсюда и нумерация с первой.
     
  24. Koc

    Koc Активный пользователь

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    idNews: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21

    Показ начинается с 3 page
    3rd page:
    21, 20, 19, 18, 17, 16, 15, 14, 13, 12
    2nd page:
    11, 10, 9, 8, 7, 6, 5, 4, 3, 2
    1st page:
    1

    Ну и что тут такого? В большинстве случаев сейчас так:
    1st page:
    21, 20, 19, 18, 17, 16, 15, 14, 13, 12
    2nd page:
    11, 10, 9, 8, 7, 6, 5, 4, 3, 2
    3rd page:
    1

    idNews: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31

    4th page:
    31, 30, 29, 28, 27, 26, 25, 24, 23, 22
    3rd page:
    21, 20, 19, 18, 17, 16, 15, 14, 13, 12
    2nd page:
    11, 10, 9, 8, 7, 6, 5, 4, 3, 2
    1st page:
    1
    Что и куда уехало?
     
  25. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.340
    Симпатии:
    44
    и тут мы добавляем 22-ю...