За последние 24 часа нас посетили 19376 программистов и 1665 роботов. Сейчас ищут 1152 программиста ...

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

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

  1. armadillo

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

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
  2. armadillo

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

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
  3. md5

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

    С нами с:
    29 янв 2007
    Сообщения:
    250
    Симпатии:
    0
    смотрится ужасно
    это вобще бред пихать все страницы в селект
     
  4. dark-demon

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

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    Sergey89, что мешает написать вместо ёлочки цифру четыре и не мучать пользователя всплывающими подсказками?
     
  5. Sergey89

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

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    dark-demon если кому-то надо будет, он напишет цифру 4, кому-то ваще эта цифра не нужна будет и он напишет ..., а мне нра ёлочки.
     
  6. dark-demon

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

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    а мне нра смайлег :)

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

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

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    dark-demon мне смайлег тоже нра :) я бы ваще не стал никуда тыркать, а ввёл бы в input. А ёлочки это так, для красивости.
     
  8. decoder

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

    С нами с:
    11 фев 2006
    Сообщения:
    469
    Симпатии:
    0
    Hight
    По-моему, dark-demon говорил о том, что обычно между соседними номерами многотоичие не ставят :)
    Надо будет подумать тоже на тему того, как правильно циферки вывести :) Допустим, что всего стрниц 20. ("Быстрый переход" с input я тут не рассматриваю)
    1, 2, 3, ..., 18, 19, 20

    Если я нажимаю на 3, то я не хочу видеть
    1, 2, 3, ..., 4, ..., 18, 19, 20
    А скорее что-то вроде
    1, 2, 3, 4, 5, ... 10, 11, 12, ... 18, 19, 20

    (10, 11, 12 я "вывел" только в первом случае, но надо было и в первом. Просто отталкивался от Вашего варианта).
    При первом взгляде на эту проблему вижу такое решение, которое, наверное, все-таки еще требует доработки...
     
  9. Mr.Gordon

    Mr.Gordon Активный пользователь

    С нами с:
    2 авг 2007
    Сообщения:
    37
    Симпатии:
    0
  10. bullder

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

    С нами с:
    25 янв 2008
    Сообщения:
    4
    Симпатии:
    0
    Кстати очень показательный пример:
    Код (Text):
    1. mysql_query("SELECT * FROM `news`  ORDER BY `news_id` DESC LIMIT $start,$news_row");
    Довольно удобная конструкция с LIMIT но на мой взгляд выборка всей таблицы:
    Код (Text):
    1. $r2 = mysql_query("SELECT * FROM `news`");
    лишь для того что бы подсчитать количество элементов в таблице через чур грубо... конечно в этом случае можно просто хранить количество записей в отдельном месте и инкрементировать при добавлении в таблицу новой записи или всё так производительность mysql позволяеть делать такого рода запросы...

    хм... с другой стороны если изначально SELECT содержит WHERE и предугадать количество выбранных записей спрогнозировать не возможно... неужели всё равно придётся делать два SELECT? один для определения количества записей другой уже непосредственно с можификатором LIMIT???? как то не рационально...
     
  11. Sergey89

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

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    [sql]SELECT COUNT(*) AS `count` FROM `news`[/sql]
     
  12. armadillo

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

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    Выбирать всю таблицу для подсчета записей конечно не годится.

    варианта два:
    1) передавать один запрос и принимать его так:
    PHP:
    1. $this->sql='SELECT SQL_CALC_FOUND_ROWS '.$sql.' limit '.($curpage*$perpage).', '.$perpage;
    2.  
    2) иметь возможность передавать два запроса - один для вывода, а другой select count(*)
    для больших баз так будет быстрее, плюс сам запрос на подсчет часто можно написать быстрее (убрать часть jeft join и т.п.)
     
  13. bullder

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

    С нами с:
    25 янв 2008
    Сообщения:
    4
    Симпатии:
    0
    Хм действительно как то забыл про SELECT COUNT(*)

    извиняйте за головотяпство...

    но показательно что для получения количества записей выше такой же начинающий видимо как и я использует вместо этого конструкцию:

    Код (Text):
    1. #  $r2 = mysql_query("SELECT * FROM `news`");
    2. #  $num = mysql_num_rows($r2);
     
  14. DZEN

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

    С нами с:
    10 сен 2007
    Сообщения:
    250
    Симпатии:
    0
    Гламурный пагинатор 0.1, из стадии преальфы так и не вышел, но в админках до сих пор пользуюсь.
    PHP:
    1.  
    2. function LinkBar($page, $pages_count, $link)
    3. {
    4.     if($pages_count > 1) echo '<b class="head">Страницы :</b> '; else return;
    5.     if( $page > $pages_count || $page < 1 ) return;
    6.     if( $pages_count > 10 && $page > 9 ) echo '<a href="'.$link.$U.'page=1" style="color:crimson">1</a>';
    7.     if( $page-19 > 1 )
    8.     {
    9.         $a = floor($page/10); $a++; $a=(($a*10)+1)-20;
    10.         echo ' <a href="'.$link.$U.'page='.$a.'"  style="color:orange">'.$a.'</a> ';
    11.     }
    12.     $j = 1; $k = 10;
    13.     if( $page >= 10 ) $j=$page-5; $k=$page+5;
    14.     for ($j; $j <= $k; $j++)
    15.     {
    16.         if ($j == $pages_count+1) break;
    17.         if ($j == $page) echo ' <a><b style="color:steelblue" >'.$j.'</b></a> '; else echo ' <a href="'.$link.$U.'page='.$j.'">'.$j.'</a> ';
    18.     }
    19.     if( $page+10 < $pages_count ) $a = floor($page/10); $a++; $a=($a*10)+1; echo ' <a href="'.$link.$U.'page='.$a.'"  style="color:blue">'.$a.'</a> ';
    20.     if( $pages_count-5 > $page && $pages_count > 10 ) echo '<a href="'.$link.$U.'page='.$pages_count.'"  style="color:lime">'.$pages_count.'</a>';
    21.     elseif( $pages_count-3 > $page && $pages_count < 20 && $pages_count > 10) echo '<a href="'.$link.$U.'page='.$pages_count.'"  style="color:lime">'.$pages_count.'</a>';
    22. }
    23. // $perpage - результатов на страницу
    24. // $query - запрос возвращающий количество результатов COUNT(*) AS `size`
    25. // $link - ссылка страницы
    26. function LinkSender($perpage = 10, $count, $query, $link)
    27. {
    28.     if (empty($_GET['page']) || ($_GET['page'] <= 0)) $page = 1;
    29.     else $page = (int) $_GET['page'];
    30.     $c = mysql_query($count);
    31.     if(!$c || mysql_num_rows($c) < 1 ) return false;
    32.     $c = mysql_fetch_assoc($c);
    33.     $c = $c['size'];
    34.     if(!isset($c)) return false;
    35.     if($c == 0) return false;
    36.     $count = $c;   
    37.     $pages_count = ceil($count / $perpage);
    38.     if ($page > $pages_count) $page = $pages_count;
    39.     $start_pos = ($page - 1) * $perpage;
    40.     if($start_pos == NULL) $start_pos = 0;
    41.     echo '<p>';
    42.     LinkBar($page, $pages_count, $link);
    43.     echo '</p>';
    44.     $limited = $query.' LIMIT '.$start_pos.', '.$perpage;
    45.     $result = mysql_query($limited);
    46.     return $result;
    47. }
     
  15. DZEN

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

    С нами с:
    10 сен 2007
    Сообщения:
    250
    Симпатии:
    0
    Комрады, а как вы разбиваете на страницы результаты поиска по базе данных?
    В смысле сам запрос выдающий количество результатов будет тоже проводить поиск, не экономно для ресурсов...
    Может есть другие варианты?
     
  16. 440Hz

    440Hz Старожил
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    есть. скрипт выдает для примера первые 10 рещультатов. отдает страницу и потом продолжает формирование страниц в кеш, ну или хотя бы готовил еще одну. следующую

    но оно надо?

    если конечно сайт не с бешенной посещаемостью.
     
  17. dark-demon

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

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    DZEN, это совершенно разные поиски.
    1. найти n первых записей удовлетворяющих условиям
    2. найти общее количество записей удовлетворяющих условиям
    если там можно произвести промежуточные кэширования - нормальная субд его сделат.
     
  18. armadillo

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

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
     
  19. DZEN

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

    С нами с:
    10 сен 2007
    Сообщения:
    250
    Симпатии:
    0
    1.5-2 тыщи в день. Только вот сколько будет пользоваться поиском мои способности предсказания будущего мне не говорят :).

    Так я хочу знать где это можно контролировать и как это лучше сделать, поэтому сюда и пишу а не смотрю в книгу `PHP для чайников`. Смотрите мою подпись и поймете почему я к каждому вопросу подхожу там скрупулезно :wink: .
     
  20. dark-demon

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

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    лучше чем два отдельных запроса - не получится.
     
  21. DZEN

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

    С нами с:
    10 сен 2007
    Сообщения:
    250
    Симпатии:
    0
    Есть вариант без вывода количества страниц.
    Искать с лимитом 11, выводить 10 если есть 11 запись - пишем ссылку `дальше`.
    Ищем с 10-й записи по 21 и т.д.
    Выводить номер записи здесь просто, а сколько страниц всего - даже не искать.
    Рисовать ссылки `назад` и `вперед`, поиск все-таки а не просмотр рейтингов.
     
  22. RomanBush

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

    С нами с:
    5 дек 2007
    Сообщения:
    798
    Симпатии:
    0
    Адрес:
    200 км от Москвы
    Хм. Интересный вариант.
    count(*) - работает быстро. :)

    А что-то не пойму, а чем конструкция "LIMIT" не угодила?
     
  23. DZEN

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

    С нами с:
    10 сен 2007
    Сообщения:
    250
    Симпатии:
    0
    Что-то вроде этого -
    [sql]SELECT `id_record`, `name`, `small_text`, `normal_text`, `full_text`
    FROM `records`
    WHERE `state` <> 0 AND `data` > 1
    AND ( `small_text` REGEXP('search') OR `normal_text` REGEXP('search') OR `full_text` REGEXP('search') )
    ORDER BY `special` DESC, `name` ASC LIMIT 100;[/sql]
    Куда ещё быстрый COUNT(*) лепить?
     
  24. armadillo

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

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    тут union вроде должен быть быстрее. и поиск по тексту мягко говоря не самый удачный.
     
  25. DZEN

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

    С нами с:
    10 сен 2007
    Сообщения:
    250
    Симпатии:
    0
    Это только пример, UNION быстрее работает в этом случае 100%.
    А насчет поиска по тексту, так я вообще больше ничего не пишу.
    CI, кодировки, латиница/кирилица - в одно время меня достали, и больше ничем кроме `пустого` REGEXP не пользуюсь.
    Если есть 95% гарантия что другой вариант будет работать лучше или быстрее, то всегда рад посмотреть пример.
    Больше нет предложений по поводу пагинатора :)?