ное 13
Digg
Stumbleupon
Technorati
Delicious
Svejo.Net

PHP: Simple pagination script (digg.com style)

… или как се печелят $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;

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


Author: katsarov

8 Коментари

Гост :P
ноември 13, 2007

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

katsarov
ноември 14, 2007

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

$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 … малко ми е трудно да си го представя…

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

katsarov
ноември 14, 2007
<?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….

Поздрави

stenly80
март 7, 2008

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

katsarov
март 8, 2008

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

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

Поздрави

gogo
март 18, 2008

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

katsarov
март 18, 2008

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

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

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

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

gogo
март 18, 2008

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

Comments RSS TrackBack Identifier URI

Вашият коментар