Начало > Без категория > PHP: Simple pagination script (digg.com style)

PHP: Simple pagination script (digg.com style)

13 ноември, 2007 Коментирай Go to comments

… или как се печелят $50 за 5мин ;)

CSS стилът (кой каквито цветове му харесват… клиента искаше сини полета с червен hover и бял текст):

.pages {
    padding: 1em;
    margin-top: 10px;
    margin-bottom: 10px;
    margin-left: 70px;
    clear: left;
    font-size: 85%;
} 
 
.pages a, .pages span {
    display: block;
    float: left;
    padding: 0.2em 0.5em;
    margin-right: 0.1em;
    border: 1px solid #fff;
    background: #fff;
} 
 
.pages span.current {
    border: 1px solid #2E6AB1;
    font-weight: bold;
    background: #2E6AB1;
    color: #fff;
} 
 
.pages a {
    border: 1px solid #9AAFE5;
    color: #2E6AB1;
    text-decoration: none;
}
.pages a:visited {
    color: #2E6AB1;
} 
 
.pages a:hover {
    border-color: #2E6AB1;
} 
 
.pages a.nextprev {
    font-weight: bold;
} 
 
.pages span.nextprev {
    color: #666666;
} 
 
.pages span.nextprev {
        border: 1px solid #dddddd;
        color: #999999;
}

Правим връзка с базата данни…

Взимаме $offset от $_GET[], за да разберем къде иска да отиде потребителят;
Задаваме $limit за максимум резултати на страница;
И взимаме общият брой записи в базата данни… забележете, че ползваме COUNT(id), а не mysql_num_rows()

$offset = $_GET['offset'];
/// Limit of the data displayed per page
$limit = 15;
// getting number of rows
$total = mysql_fetch_array(mysql_query('SELECT COUNT(id)
FROM countries AS total'));
 
?>

Ако $offset не е зададен правим $start равно на нула, в противен случай равно на $offset…

(!$offset ? $start = 0 : $start = $offset);
?>

Заявката към базата данни:
взимаме всички полета от таблицата ‘countries’, подреждаме ги по ‘id’…
… и може би най-важната част при pagination скриптовете: LIMIT $start, $limit“)
$start ни е мястото от което започваме (или колко резултата ще прескочим), $limit е максимума резултати на страница

$query = mysql_query("SELECT * FROM countries
ORDER BY id LIMIT $start, $limit ")
or die('Query failed: ' . mysql_error());
?>

Извеждането на резултатите…

while ($row = mysql_fetch_array($query)) {
    echo $row['country_name'];
    echo '';
}
?>

Ако броя резултати е по-голям от $limit показваме страниците, $paginas е всички резултати разделени на $limit като го закръгламе чрез ceil()

if ($total[0] > $limit) {
  $paginas = ceil(($total[0]/$limit));
 
?>

За да няма връзка към предишни страници когато всъщност нямаме такива се налага една if() клауза.
Ако $offset е по-малко или равно на нула – показваме само текст. В противен случай показваме връзка като изваждаме текущият $offset от $limit и дефакто получаваме предишната страница…

if($offset <= '0'){
    ?>
    <span class="nextprev">« Previous</span>
    } else {
//else if we have previous pages show link 'Previous'
    echo '<a href="http://katsarov.seloto.net/wp-admin/?offset=%27%20.%20%28$offset%20-%20$limit%29%20.%20%27">
« Previous</a>';
} ?&gt;

Време е да изведем списъка със страници. В случая тук също имаме една допълнителна проверка на коя страница се намира потребителят. По този начин текущата страница става без линк и се оцветява в друг цвят…

for ($i = 0; $i &lt; ($paginas); $i++) {
  if ($i+1 == (($offset/$limit)+1) ) {
  //if its current page don't show link
      ?&gt;
 
        } else {
  //else if its not current page show link
  ?&gt;
   <a href="http://katsarov.seloto.net/wp-admin/?offset=%3C?php%20echo%20$i%20*%20$limit;%20?%3E"></a>
  } ?&gt;

Ето още една проверка. Този път дали имаме следваща страница. Ако нямаме се показва само текст без връзка, в противен случай правим връзка към следващата страница, която е $offset + $limit

if($offset &gt;= ($total['0'] - $limit)){
    ?&gt;
    <span class="nextprev">Next »</span>
    } else {
//else if we have next pages show 'Next' with link
    echo '<a href="http://katsarov.seloto.net/wp-admin/?offset=%27%20.%20%28$offset%20+%20$limit%29%20.%20%27">
Next »</a>';
} ?&gt;

Ето тук има демо на скрипта

Ето го и целият код:

// Database Connection Config
$dbhost = "localhost"; // database host
$dbuser = "root"; // database user
$dbpass = "dbpass"; // database pass
$dbname = "dbname"; // database name 
 
// Database Connection
$db_connect = mysql_connect($dbhost, $dbuser, $dbpass);
if (!$db_connect) {
    die('Could not connect: ' . mysql_error());
}
else {
    mysql_select_db($dbname);
}
$offset = $_GET['offset'];
/// Limit of the data displayed per page
$limit = 15;
// getting number of rows
$total = mysql_fetch_array(mysql_query('SELECT
COUNT(id) FROM countries AS total')); 
 
(!$offset ? $start = 0 : $start = $offset);
// database query
$query = mysql_query("SELECT * FROM countries
ORDER BY id LIMIT $start, $limit ")
or die('Query failed: ' . mysql_error());
//showng query in circle
while ($row = mysql_fetch_array($query)) {
    echo $row['country_name'];
    echo '';
}
//end showing query
if ($total[0] &gt; $limit) {
  $paginas = ceil(($total[0]/$limit)); 
 
  if (!$offset) {
   $comeco = 0;
  } else {
   $comeco = $offset;
  }
?&gt;
<p class="pages">//if we don't have previous pages show only style without link
if($offset &lt;= '0'){
    ?&gt;
    <span class="nextprev">« Previous</span>
    } else {
//else if we have previous pages show link 'Previous'
    echo '<a href="http://katsarov.seloto.net/wp-admin/?offset=%27%20.%20%28$offset%20-%20$limit%29%20.%20%27">
« Previous</a>';
}
//circle that shows pages
  for ($i = 0; $i &lt; ($paginas); $i++) {
  if ($i+1 == (($offset/$limit)+1) ) {
  //if its current page don't show link
      ?&gt;
 
        } else {
  //else if its not current page show link
  ?&gt;
   <a href="http://katsarov.seloto.net/wp-admin/?offset=%3C?php%20echo%20$i%20*%20$limit;%20?%3E"></a>
  }
}
//if we don't have next pages show only 'Next' without link
if($offset &gt;= ($total['0'] - $limit)){
    ?&gt;
    <span class="nextprev">Next »</span>
    } else {
//else if we have next pages show 'Next' with link
    echo '<a href="http://katsarov.seloto.net/wp-admin/?offset=%27%20.%20%28$offset%20+%20$limit%29%20.%20%27">
Next »</a>';
}
?&gt;
 
?&gt;

Ето отново демото на скрипта в случай, че на някой не му се скролва ;)

Сподели:
  • Digg
  • del.icio.us
  • Reddit
  • StumbleUpon
  • Technorati
  • Facebook
  • Google Bookmarks
  • Netvibes
  • Add to favorites
  • email
  • MySpace
  • RSS
  • Twitter
  1. Гост :P
    13 ноември, 2007 в 22:39 | #1

    А как ще стане без db, а с файлове от директория ?

  2. 14 ноември, 2007 в 01:59 | #2

    хм, интересен въпрос. Ако имаш в впредвид да лимитира броя на файловете в директорията за всяка страница… става почти по същият начин (ето една готова функция за преброяване на файловете)

    $cnt=0;
    $dirname="./";
    $dh = opendir($dirname);
    while ($dave=readdir($dh))
    {
    if(!is_dir($dave)){
    print "$dave <br>";
    $cnt=$cnt+1;
    }
    }
    closedir ($dh);
     
    print $cnt-2;

    … с това се взима броят на файловете…
    лимите може да стане с: (това не е пробвано!)
    while ($dave=readdir($dh) && $cnt <= $limit)
    … само че има нещо което не ми е ясно… как ще започва показването на файловете от $offset … малко ми е трудно да си го представя…

    иначе за четене от текстови файл би трябвало да стане по-лесно…

  3. 14 ноември, 2007 в 02:15 | #3
    <?php
    if (!$_GET["start"]) $_GET["start"] = 1;
    $show = 10;
     
    $dir = ".";
    $thedir = opendir($dir);
    while (false !== ($file = readdir($thedir))){
    if (in_array($file, array(".", ".."))) continue;
    $files[] = $file;
    }
    $pages = ceil(count($files)/$show);
     
    foreach ($files as $file){
    $nr++;
    if ($nr >= $_GET["start"] && $nr < $_GET["start"]+$show){
    print "<li$nr. $file\n";
    }
    }
     
    ?>

    масиви разбира се :)
    остава само да се сглобят. Много е лесно и работи!
    Ако искаш да се показват и директориите махни if(!is_dir….

    Поздрави

  4. stenly80
    7 март, 2008 в 13:48 | #4

    a Как може да се направи скрипта ако примерно имаме 100 страници да се показва prev 1 2 3 4 ….. 97 98 99 100 next,а не както е досега защото се получава прекалено дълго.
    10x предварително

  5. 8 март, 2008 в 05:09 | #5

    Пробвай този пример: http://www.strangerstudios.com/sandbox/pagination/diggstyle.php

    доста по-добър е от моето решение и си е врътнато като функцийка, така че се използва доста по-добре. Ако не се справиш – пиши, за да помагам.

    Поздрави

  6. gogo
    18 март, 2008 в 12:57 | #6

    А бе не мога да разбера защо ми дава грешка: Notice: Undefined index: offset in C:\wamp\www\NewSite\index2.php on line 105
    Точно където ползваш $_GET?Pls help!!!

  7. 18 март, 2008 в 14:04 | #7

    @gogo, не е грешка, а notice – само те информира, че $offset не е дефиниран.
    Ако не ти се занимава да ги изключваш (в php.ini слагаш едно ~ пред E_NOTICE)… та ако не ти се занимава слагаш след $offset = $_GET['offset'] това :

    if(!isset($offset)){
    $offset = 10;
    }

    по този начин ако е празно $offset, ще приеме стойност 10

    Дано да ти свърши работа. Бтв, може да ги изключиш тези E_NOTICE :)

  8. gogo
    18 март, 2008 в 16:27 | #8

    Мерси за съвета:)!Само че като set-на offset пак ми го вади този Notice,така че сигурно ще е по-добре да си го изключа;)!

  9. 26 юни, 2008 в 23:24 | #9

    Ето какво получавам на страницата на демото ти:
    Warning: mysql_connect() [function.mysql-connect]: Access denied for user ‘grehoveu_cargo’@'localhost’ (using password: YES) in /home/grehoveu/public_html/work.seloto.net/pages/pagination.php on line 62
    Could not connect: Access denied for user ‘grehoveu_cargo’@'localhost’ (using password: YES)

  10. 29 юни, 2008 в 02:39 | #10

    Значи копирах целия код и след като си направих промените по конекта и дб-то ми дава следната грешка:

    Parse error: syntax error, unexpected ‘;’ in C:\Program Files\EasyPHP 2.0b1\www\my_files\paging11.php on line 33
    А ето това ми е 33 ред:
    if ($total[0] > $limit) {
    Забелязах, че къдравата скобичка не е затворена…, но ми е малко сложничък кода

  11. 29 юни, 2008 в 02:40 | #11

    и не съм много навътре в php-то ако може да помогнеш, много ще те зарадваш :)

  12. 29 юни, 2008 в 17:40 | #12

    @Daniel, ако си копирал кода без да натиснеш „View Code“ може да си копирал не каквото трябва.
    Пробвай да копираш кода от „View Code“

    @Image Pik, при първа възможнос ще оправя демото. Но като цяло външния вид си е като на digg.com :)

  1. 24 юни, 2008 в 16:03 | #1
Коментарите са затворени
blog comments powered by Disqus