I’ve been meaning to simplify my work / life by creating some classes that I can use to streamline a lot of the projects that I work on. I found myself with some time this week and finally took a small step in that direction by creating a pagination class.
Up until now I’ve used a function that I wrote way back when for paging. It was clunky, kludgy, and limited. I looked around at what was available online and what I found was, for the most part, clunky, kludgy, and limited.
Starting from my existing code, I laid out some goals for how I wanted my new pagination object to work:
- It had to be very simple to integrate. I wanted to be able to drop it into a file and have it just work.
- The output had to be semantic, valid (X)HTML that would be easy to style with CSS.
- I wanted options for how the links would display.
- It needed to have options to output clean URLs (for when I’m using mod rewrite) or normal URLs with ugly query strings.
- It needed the option of using sessions to store SQL queries since, much of the time, this would be necessary when using clean URLs.
- It had to be drop-dead simple to configure options, such as how many pages to display per page, enabling mod rewrite functionality, enabling the use of session data, etc.
The idea for using sessions and clean URLs came from Ben Jamieson / Thyme Online. I’m also going to credit him with the idea for highly compartmentalizing the code used in the class (he has a highly compartmentalized pagination class of his own with sessions and clean URLs…) even though I remember what his code looked like when I first met him and I think this may be a case of the student becoming the master!
If you’re wondering why I wrote my own class instead of just using his, well, there were a couple of reasons:
- I wanted the practice (I re-read the chapter on OOP in my PHP book before starting).
- I’m an idiot: I was concerned about security and I didn’t realize the session data was only storing a session ID in the client side cookie and not the actual SQL queries. I initially wrote this class to include Alexander Valyalkin’s most excellent md5_ encryption and decryption functions.
- There were some things I wanted to do differently.
- And because I already had my own paging code that I wanted to adapt.
If you already have something in place to handle pagination, a lot of this code will probably look familiar — there aren’t that many ways to skin this particular cat — but hopefully this code is clean enough and reusable enough that some people will find it useful.
A Simple Example
<?php
include_once('class.pagination.php');
$sql = "SELECT * FROM table_name";
$paging = new pagination();
$result = mysql_query($paging->paginate($sql));
while ($record = mysql_fetch_assoc())
{
// Output records here
}
print($paging->getLinks());
print("<p>".$paging->getCount()."</p>");
?>
The above example is the simplest usage. The class is included, the object is initialized, the SQL code is passed and returned with the LIMIT clause appended (note: it will replace any existing limit clause) and the links are output.
Sample Output
Displaying 1 to 5 of 13
Displaying 81 to 90 of 130
For large sets of data, ten or more pages, first and last links are added to let users quickly jump to the beginning or end of the data set. Otherwise, just the pages and previous/next links are displayed. You can change that by passing an optional variable to the getLinks() function or, if you’re going to output multiple sets of paging links on a page, you can override the default format via the setDisplayOptions() function (see description of this function below for more details).
Available Functions
paginate($sql) – This function initializes several variables and returns a modified SQL statement with a LIMIT clause appended to it.
setDisplayOptions($x) – This function changes how pagination links are output for a given page. It takes a numeric value between 1 and 4:
- Only show the first and last links for large data sets (ten or more pages). Only show previous link when not on the first page. Only show next link when not on the last page. This is the default setting.
- Always show first and last links. Always show previous and next links.
- Never show first and last links but always show previous and next links (the Flickr option).
- Never show first and last links. Only show previous link when not on the first page. Only show next link when not on the last page.
You can achieve the exact same functionality by passing this variable in the getLinks() function. Both of the following examples output the same thing:
<?php
// Example one
$paging->setDisplayOptions(3);
print($paging->getLinks());
// Example two
print($paging->getLinks(3));
?>
setPageSize($x) – Override the default number of items to display per page. The default is 25.
setModRewrite(TRUE) – The default value is FALSE. Override this if you plan to use mod_rewrite to create clean URLs. If you don’t know what this is, leave it alone.
setUseSessions(TRUE) – The default value is FALSE. Override this if you have complex SQL statements that you don’t want to pass via query strings. You’ll probably need to enable this if you’re using clean URLs.
setSessionName($name) – This just exists to prevent any possible conflicts with existing code. The default session name is ‘searchdata‘. If, by any chance, you already use a session variable with that name, you can override the name used by the pagination class.
This function can also be used if you plan to store multiple SQL queries by assigning a unique session name for each query.
getSQL() – What goes up, must come down — or better put: what is input, must be output. You pass a SQL statement to the pagination object; this function returns that SQL statement to you with the LIMIT clause appended to it.
getCount() – This returns the “Displaying from x to y of z” string. It gets its own function so that it is easy to omit if don’t want to display it.
getLinks($x) – This is the meat and potatoes. This function returns the list of links for output. It accepts the same numeric option that setDisplayOptions($x) uses.
Miscellaneous Notes
Regardless of whether you use clean URLs or not, the the current page is determined by the $_GET['page'] variable. The page variable always needs to be the last part of the query string or path. Examples:
- domain.com/articles/title/5/
- domain.com/article.php?name=title&page=5
- domain.com/search.php?keywords=xyz&sort=desc&page=2
The first example above is using mod_rewrite.
To use sessions, you first have to initialize the session data with:
<?php
session_start();
?>
If you are using cookie-based sessions, you must call session_start() before anything is output to the browser. For more information on how to use session_start(), see the php.net website.
You can view the source code of this page and the associated stylesheet to see how the links are output and how I’ve styled them.
If you have suggestions regarding this class, please leave a comment. Also, this isn’t heavily tested, so if you find a bug (I’m sure there will be some) please let me know about it.
PREVIOUS: One Month Birthday | NEXT: Make the Logo Bigger
Nice! Thanks. I might use this someday. Will let you know if I do.
thankyou verymuch.. your script is very useful for my project.
Hi, I used your class but seem to have the following problem:
The link on the page numbers, etc. does not come out correctly unless I change your code in the class to the actual page where I’m calling the class on the following line:
if (substr($path, -1) != “?” && substr($path, -1) != “&”) $path .= “page.php?”;
See where I changed the path to page.php?. It now works great, but I want to use this for other pages too so I must be doing something wrong. Any ideas?