phppaginationlogic

paging like stackoverflow's


i'm a newbie in php especially on making pagination.

my question is, how to make paging like stackoverflow's pagination?
i mean paging like this :

1 ... 5 6 7 8 9 ... 25
(the first number and the last number is always appear, but in the middle only 5 numbers with the selected page absolutely in the middle)

in php i have tried making paging,

<?php

//Show page links
for($i=1; $i<=$pages; $i++)
{
    echo '<li id="'.$i.'">'.$i.'</li>';
}

?>

but it will be shown all of pages like

1 2 3 4 5 6 7 8 9 10 etc

any body have simple logic example to solve this problem?
many thanks :)


Solution

  • Below is a snippet from a general pagination class1 I wrote a few years ago. I have edited it to show the relevant parts only.

    // cntAround is the number of pages to show before and after the current
    function renderNavigation($cntAround = 1) {
        $out      = '';
        $isGap    = false; // A "gap" is the pages to skip
        $current  = // Current page
        $cntPages = // Total number of pages
    
        for ($i = 0; $i < $pages; $i++) { // Run through pages
            $isGap = false;
    
            // Are we at a gap?
            if ($cntAround >= 0 && $i > 0 && $i < $cntPages - 1 && abs($i - $current) > $cntAround) { // If beyond "cntAround" and not first or last.
                $isGap    = true;
    
                // Skip to next linked item (or last if we've already run past the current page)
                $i = ($i < $current ? $current - $cntAround : $cntPages - 1) - 1;
            }
    
            $lnk = ($isGap ? '...' : ($i + 1)); // If gap, write ellipsis, else page number
            if ($i != $current && !$isGap) { // Do not link gaps and current
                $lnk = '<a href="?page=' . ($i + 1) . '">' . $lnk . '</a>';
            }
            $out .= "\t<li>" . $lnk . "</li>\n"; // Wrap in list items
        }
    
        return "<ul>\n" . $out . '</ul>'; // Wrap in list
    }
    

    Example 1

    cntAround = 1, current = 5, cntPages = 9:

    [1] ... [4] 5 [6] ... [9]
    

    Example 2

    cntAround = 3, current = 5, cntPages = 11:

    [1] [2] [3] [4] 5 [6] [7] [8] ... [11]
    

    1) Article is in Danish. Google Translate'd version is here.