OOP Pagination Script

Coding Critique is the place to post source code for peer review by other members of DevNetwork. Any kind of code can be posted. Code posted does not have to be limited to PHP. All members are invited to contribute constructive criticism with the goal of improving the code. Posted code should include some background information about it and what areas you specifically would like help with.

Popular code excerpts may be moved to "Code Snippets" by the moderators.

Moderator: General Moderators

Post Reply
FunkyDude
Forum Newbie
Posts: 8
Joined: Mon Dec 15, 2008 5:19 pm

OOP Pagination Script

Post by FunkyDude »

~pickle | Please use [ code=html ], [ code=php ], etc tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read: :arrow: Posting Code in the Forums to learn how to do it too.


This script can get a list of results from a database (images, articles, whatever) and paginate it into multiple pages. You choose how many to display per page. You also use a while loop to loop through the results (this is where you would build your html layout). It's sloppy but it works and it's one of my first attempts at OOP.

Here's a sample layout, change the SQL request to fit your needs, also adjust the while loop to match your database fields.

Code: Select all

<?php
 
$conn = mysql_connect('localhost', 'user', 'pwd') or die ('Cannot connect to server');
mysql_select_db('database_name') or die ('Cannot open database');
include('pagination.php');
 
// call on the pagination object, ('current set added to the query string', 'your sql request', 'per page', 'optional', 'optional')
$pg = new Pagination('1', 'SELECT * FROM articles ORDER BY created DESC', '5', '', '');
 
 
// using $pg->currSet_result you can fetch data and loop through the results, change the html to fit your layout
while ($row = $pg->currSet_result->fetch_assoc()) {
        echo "<h1>".$row['title']."</h1>\n";
        echo "<p id=\"pressAddedDate\">Added ".$row['created']."</p>\n";
        echo "<p>".$row['message']."</p>\n";
        echo "<p style=\"clear:both;padding:0px;line-height:10px;height:10px;margin:0;\">&nbsp;</p>\n";
        }
 
 
// show navigation links (I'm not going to post the css file, but if you inspect the id's and class' you can figure out how to skin the page/fwd/bck links)
echo $pg->navLink;
 
// display pagination info
echo $pg->navigation;
 
?>
Here's the pagination script, I was having trouble with <div>'s not display correctly so I resorted to the old school tables for stability.

Code: Select all

<?php
 
class Pagination {
    
    function __construct($table_result_id, $sql_select_statement, $perPage, $conn, $component) {
        
    $max_result = $conn->query($sql_select_statement) or die (mysqli_error($conn));    
    $this->max_results = $max_result->num_rows;
    
    // figure out if any other result sets being paginated and build the query (this way you don't lose the page your on for any particular result set)
    if ($table_result_id > 1) {
        $set_reference = 0;
        while ($set_reference < $table_result_id) {
            $currSetQuery .= "cs".$set_reference++."";
        }
    }
    
    $set_reference++;
    // current set of database results, compounded into an sql statement    
    // $table_result_id is the identity of the particular table/result (e.g. latest news = cs1, or latest images = cs2, etc.) 1 digit numeric reference value 
    $currSet = $_GET['cs'.$table_result_id];
    // find starting row position for each page
    $startPosition = ($currSet * $perPage);
    // build sql statement for current set
    $sql_currSet = $sql_select_statement.' LIMIT '.$startPosition.', '.$perPage;
    // create a db query based on the settings above
    $currSet_result = $conn->query($sql_currSet) or die (mysqli_error($conn));
    
    // get the count number of the last result
    $modular = $this->max_results % $perPage;
    $firstEntryLastPage = $this->max_results - $modular;
    if ($startPosition == $firstEntryLastPage ) {
        $endPosition = $this->max_results;
        } else {
        $endPosition = $currSet * $perPage + $perPage;
        }
        
    // calculate total pages
    $totalPages = $firstEntryLastPage / $perPage;
    if ($modular > 0) {
        $totalPages = $totalPages + 1;
    }
    
    // render navigation links
    $i = 0;
    while ($i < $totalPages) {
                    ## create fwd, bck, first, and last page links
                    $nextPage = $currSet + 1;
                    if ($nextPage < $totalPages) {
                        $fwdPage = "<a href=\"".$_SERVER['SCRIPT_NAME']."?".$component."cs".$table_result_id."=".$nextPage."\">Next</a>";
                        $lastPage = "<a href=\"".$_SERVER['SCRIPT_NAME']."?".$component."cs".$table_result_id."=".($totalPages - 1)."\">Last</a>";
                    } else {
                        $fwdPage = "";
                    }
                    $prevPage = $currSet - 1;
                    if ($currSet > 0) {
                        $rwdPage = "<a href=\"".$_SERVER['SCRIPT_NAME']."?".$component."cs".$table_result_id."=".$prevPage."\">Prev</a>";
                        $firstPage = "<a href=\"".$_SERVER['SCRIPT_NAME']."?".$component."cs".$table_result_id."=0\">First</a>";
                    } else {
                        $rwdPage = "";
                    }
                    ## end fwd and bck section
        if ($i == $currSet) {
            $style = "\t\t<td class=\"activePage_cs".$table_result_id."\">";
            $pageLink = "";
            $pageLinkClose = "";
        } else {
            $style = "\t\t<td class=\"pageLink_cs".$table_result_id."\">";
            $pageLink = "<a href=\"".$_SERVER['SCRIPT_NAME']."?".$component."cs".$table_result_id."=".$i."\">";
            $pageLinkClose = "</a>";
            }
    // add each link to an array
    $navLink[$i] = $style.$pageLink.++$i.$pageLinkClose."</td>\n";
    }
    // extract the array into a variable
    if ($navLink == '') {
        echo '';
    } else {
    foreach ($navLink as $navLink1) { $navLink2 .= $navLink1." "; }
    if ($totalPages == 1) { $navLink2 = ''; }
    // put the array together in a <ul>
    $navLink2 = "\n\n\t<table cellspacing=\"0\"><tr><td class=\"navFwdBck_cs".$table_result_id."\">".$rwdPage."</td>\n".$navLink2."\t\n<td class=\"navFwdBck_cs".$table_result_id."\">".$fwdPage."</td></tr></table>\n";
    
    // building the object
    $this->navLink = $navLink2;
    $this->totalPages = $totalPages;
    $this->currSet_result = $currSet_result;
    $this->navigation = "<div class=\"navStats_cs".$table_result_id."\">".($startPosition+1)."-".$endPosition." of ".$this->max_results." | Total pages: ".$this->totalPages."</div>";
    }
 
    return $pagination;
    
    }
 
}
 
?>

~pickle | Please use [ code=html ], [ code=php ], etc tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read: :arrow: Posting Code in the Forums to learn how to do it too.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: OOP Pagination Script

Post by Christopher »

Code: Select all

// show navigation links (I'm not going to post the css file, but if you inspect the id's and class' you can figure out how to skin the page/fwd/bck links)
echo $pg->navLink;
 
// display pagination info
echo $pg->navigation;
I think it would better for these two to be methods rather than properties (unless you want people to assign to them). And give then the names you have in the comments (so you don't need comments) -- showNavigationLinks() and showPaginationInfo().
(#10850)
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: OOP Pagination Script

Post by John Cartwright »

Your script queries the entire database. Highly unrecommended.

Take a loot at some of the other pagination classes around here, you will see they manipulate the original query to perform a COUNT(*) instead of actually fetching the rows, then perform the originally query (with the LIMIT clause appropriatly attached) so only fetch the specific rows given by the pagination threshold.
Post Reply