I recently re-wrote the pagination function that I normally use for my new framework.
I have cleaned up the code immensly, added some commenting, and some css tags. I'll also explain how to use the fuction more clearly this time as a few people have been requesting me to!
Pagination, for those who don't know, is a way of pulling rows from a database (in this case MySQL) and showing only a certain amount at a time (say 10), with some prev/next links for navigating to the next/previous set of 10 results. This function will also provide a selection of numbered links in between for quicker navigation.
So, once you have the function included in your page (or linked to), you'd use it by calling the function. Here's an example:
<?
$query = "SELECT first_name FROM my_table";
$base_url = "http://www.ben-griffiths.com/";
$page_number = $_GET['0']; // This depends on how your server is setup.
$number_of_rows = 10;
$pagination = paginated_query($query,$base_url,$page_number,$number_of_rows);
?>
That will run the function, and return an array with all of our results and data. To show the data on the page we do something like this:
<?
while($result = mysql_fetch_assoc($pagination['results'])){
echo $result['first_name'];
}
?>
That will run through our 10 results, and show them on the page. Now all we need to do is show our next/prev page links, like this:
<?
echo $pagination['page_links'];
?>
Thats the most basic way of doing this - there are things to take into account though. This function uses seo friendly URL's for the page links, so you'll need to make sure your server is set up for mod_rewrite (Apache servers), or change the function where the links are created to use the old style $_GET methodology.
The function expects the very first page to be number 1, not 0 - this helps stop confusion with users who like to look at URL's - if the page number is not passed in the query string, make sure you assign it a default of 1.
The returned array also has the total pages (for showing something like "Page 1 of 19"), and total results (For showing things like "342 results found").
Here is the full source code:
<?
function paginated_query($mysql_query,$base_url,$page_number=0,$number_of_rows_to_return=20)
{
$page_number = $page_number - 1;
// If SQL_CALC_FOUND_ROWS inst in the string - add it!
if(stristr($mysql_query, 'SQL_CALC_FOUND_ROWS') === FALSE){
$mysql_query = str_replace('SELECT ', 'SELECT SQL_CALC_FOUND_ROWS ', $mysql_query);
}
// Build query for return
$offset_limit = ($page_number * $number_of_rows_to_return);
$get_results = mysql_query($mysql_query." LIMIT ".$offset_limit.", ".$number_of_rows_to_return);
// Get total number of rows
$count_rows_query = $this->normal_query("SELECT FOUND_ROWS();");
$count_rows = mysql_fetch_array($count_rows_query);
// Calculate the total pages we will have
$total_pages = ceil($count_rows[0] / $number_of_rows_to_return);
$total_pages = $total_pages;
$total_results_feedback = $count_rows[0];
$links_current_page = $page_number + 1;
// Build PREV link
if($links_current_page == 1){
$links_prev = '<span class="pagination_link">« Prev</span>';
} else {
$links_prev = '<a href="'.$base_url.($links_current_page - 1).'/"><span class="pagination_link_active">« Prev</span></a>';
}
// Build NEXT link
if($links_current_page == $total_pages){
$links_next = '<span class="pagination_link">Next »</span>';
} else {
$links_next = '<a href="'.$base_url.($links_current_page + 1).'/"><span class="pagination_link_active">Next »</span></a>';
}
// Build MIDDLE Links
$links_middle = '';
if($total_pages <= 14){
$counter = 1;
while($counter <= $total_pages){
if($counter == $links_current_page){
$links_middle .= '<a href="'.$base_url.$counter.'/"><span class="pagination_link_active_current">'.$counter.'</span></a>';
} else {
$links_middle .= '<a href="'.$base_url.$counter.'/"><span class="pagination_link_active">'.$counter.'</span></a>';
}
$counter++;
}
}
if($total_pages > 14){
if($links_current_page <= 8){
$counter = 1;
while($counter <= 10){
if($counter == $links_current_page){
$links_middle .= '<a href="'.$base_url.$counter.'/"><span class="pagination_link_active_current">'.$counter.'</span></a>';
} else {
$links_middle .= '<a href="'.$base_url.$counter.'/"><span class="pagination_link_active">'.$counter.'</span></a>';
}
$counter++;
}
$links_middle .= ' <span style="margin-right: 2px;">...</span> ';
$links_middle .= '<a href="'.$base_url.($total_pages - 1).'/"><span class="pagination_link_active">'.($total_pages - 1).'</span></a>';
$links_middle .= '<a href="'.$base_url.$total_pages.'/"><span class="pagination_link_active">'.$total_pages.'</span></a>';
}
if($links_current_page > 8 && ($links_current_page < $total_pages - 8)){
$links_middle = '<a href="'.$base_url.'1/"><span class="pagination_link_active">1</span></a>';
$links_middle .= '<a href="'.$base_url.'2/"><span class="pagination_link_active">2</span></a>';
$links_middle .= ' <span style="margin-right: 2px;">...</span> ';
$counter = $links_current_page - 4;
while($counter <= ($links_current_page + 4)){
if($counter == $links_current_page){
$links_middle .= '<a href="'.$base_url.$counter.'/"><span class="pagination_link_active_current">'.$counter.'</span></a>';
} else {
$links_middle .= '<a href="'.$base_url.$counter.'/"><span class="pagination_link_active">'.$counter.'</span></a>';
}
$counter++;
}
$links_middle .= ' <span style="margin-right: 2px;">...</span> ';
$links_middle .= '<a href="'.$base_url.($total_pages - 1).'/"><span class="pagination_link_active">'.($total_pages - 1).'</span></a>';
$links_middle .= '<a href="'.$base_url.$total_pages.'/"><span class="pagination_link_active">'.$total_pages.'</span></a>';
}
if($links_current_page > 8 && ($links_current_page >= $total_pages - 8)){
$links_middle = '<a href="'.$base_url.'1/"><span class="pagination_link_active">1</span></a>';
$links_middle .= '<a href="'.$base_url.'2/"><span class="pagination_link_active">2</span></a>';
$links_middle .= ' <span style="margin-right: 2px;">...</span> ';
$counter = $total_pages - 9;
while($counter <= $total_pages){
if($counter == $links_current_page){
$links_middle .= '<a href="'.$base_url.$counter.'/"><span class="pagination_link_active_current">'.$counter.'</span></a>';
} else {
$links_middle .= '<a href="'.$base_url.$counter.'/"><span class="pagination_link_active">'.$counter.'</span></a>';
}
$counter++;
}
}
}
// Join the PREV, MIDDLE and NEXT link blocks
$output_page_link = '<div class="pagination_links">'.$links_prev.$links_middle.$links_next.'</div>';
// If no links, build EMPTY link block
if($total_pages == 0){
$output_page_link = '<div class="pagination_links"><span class="pagination_link">« Previous</span><span class="pagination_link"><strong>1</strong></span><span class="pagination_link">Next »</span></div>';
}
// Return the array
$pagination_array = Array (
"page_links" => $output_page_link,
"results" => $get_results,
"total_pages" => ($total_pages + 1),
"total_results" => $total_results_feedback
);
return $pagination_array;
}
?>
If you have any questions, please feel free to ask in the comments below :)









© Ben Griffiths 2008