PHP Pagination
by Marc Plotz
October 06, 2009
|
Are you having to rewrite needless code every time you need
pagination on your website? Explore this simple but
effective way of building your own, re-usable PHP pagination
class.
|
Introduction
Pagination is something I always find to be a rather
painful and mind-numbing process. Most of the time I am much
more concerned about actual processes going on rather than
some little links that are just going to make navigation
somewhat easier and pageloads smaller. But the fact is that
pagination is one of things you need to do and you need to
do it right. Ever click on a "next" link on a website and
found yourself somewhere you did not intend to go? Or worse
than that in my opinion, have you ever been to a website
that has a page so long you get bored long before ever even
getting close to the content you are looking for? Did it
annoy you? Did you ever use that website again? What if that
was your website?
Well, since I can't deny that pagination is important, I
decided to write a little class that can handle all that
stuff for me without me having to worry about it too much.
You can download the example HERE. Note that in classes.php there is a
simple database connection class as well as a pagination
class. Simply create a database called paginator with the
connection details set in classes.php lines 16 to 19 and run
the example.php. The script will build the table and insert
data into it. I am not really going to go into the details
of the database class here, as I think that is beyond the
scope of this article. That said, lets look at
pagination.
It's all about the QUERY
Well, essentially, yes--it's about the query. When we are
dealing with pagination we are basically looking at what
page we are on, how many items (or rows) we want to extract
from the database on that page, and what the first and last
row should be.
When you get into it a little more closely you start to
realize that there is a little more you need to think about.
First, what if there are a hundred pages available, do you
really want to show 100 page links at the bottom of the
page? What I have come to raise is that around 5 - 10
usually works nicely. But then again, WHICH links do you
show? Obviously the page you are on should not be a link,
since it would not make sense to end up linking to the page
you are currently on. Also, if you are on, say, page 50, can
you get back to Page One or the last page with only one
click? To me all these things are important, and they are
things I took into account before building this class.
We begin by looking at what we need to do in order to
print out our data, and then we can look at the class step
for step.

Figure One: example.php
As you can see, on line 3 we include the 'classes.php'
page. Obviously where you keep this file and how you use it
on your own site is entirely up to you (isn't PHP just
beautiful?). Next we build the $params array.
This array will contain the query that will select
everything you need from the database, and is exactly how it
would be if you just wanted to print all rows out on one
long page. How we deal with this will be handled shortly. We
also define a per page value for the array. Using this we
will tell the database how many entries per page we want to
view.
On line 9 we instantiate the pagination object, and pass
the $params array into it. At this point the
object is created and the constructor for the pagination
class is run. Let us take a look at the pagination class
now.
Click here for larger image
Figure Two: pagination class
So figure two shows the basic properties and the
constructor method of our pagination class. Luckily we see
that our pagination class extends the db class, which means
that the database connection and functionality is still
available here.
public $data; = The actual information (rows) taken out
of the database.
public $query; = The query that we passed into our class
in the $params array as seen in Figure One
public $perpage; = The amount of rows to show per page,
also setup in the $params array.
public $shortest; = The shortest we want our list of
pages to be.
public $fluctuation; = the amount of pages we want to
see links to relative to our current page. So we will see
three page numbers more and three page numbers less than our
current page.
public $pg; = The current page we are on, defined
usually by $_GET['page'] (or the lack of $_GET['page'] being
set - hence 1)
public $start; = The page number that the list of page
numbers should start on. More on this later.
Looking at the __construct($params)
function, we know that this function runs when the
pagination class is instantiated.This means that before we
start running all these queries and executing logic we can
just take a few minutes to set things up nicely. We begin by
defining the "perpage" and "query" properties of our
pagination class by extracting the values from the params
array (isn't it great that you put data in one place and get
it out the other, like water in a hosepipe?). Then we run
the original query so that we can have a look to see just
how many rows need to be extracted in total. Obviously
dividing the total amount of rows by the amount of rows we
want to show per page gives us the total amount of pages
required when rounded.
Then we start to get down to the nitty gritty. Line 141
to Line 153 basically tells the class what to do if the
$_GET['page'] value is not set in the URL bar.
In these instances we simply define the current page, and
the starting page. Once we have the starting page (lets say
it is 1, in this instance), we can simply run the query
again, but this time setting constraints on how many rows we
extract from the database via LIMIT. The query
looks like this:
$this->data = parent::getArray($this->query." limit ".$this->start.", ".$this->perpage."");
which might read as
$this->data = parent::getArray($this->query." limit 1, 10");
What we are saying in the limit statement is that we
should extract data from the database starting at row 1, and
ending at row 1+10, effectively giving us the first page of
data. In essence we are simply going to be manipulating that
query in order to display the rest of the pages.
Now that we have run the constructor, lets go back to
figure one - line 11.
$data = $pagination->get_data();
The get_data(); method in the pagination
class is a very simple class that purely returns the
$data property that we created when we
instantiated--and this ran the constructor on--the
pagination class. It looks like this:

Figure Three: get_data()
Using this $data variable we can now
actually run our loop to print out the data. My example is
one of a few ways we can do this (lines 13 -19 of Figure
One). Finally, on line 21 of Figure One, we echo the
paginate() method of the pagination class. This
method looks like this:

Figure Four: paginate()
As we see above, in Figure Four, line 173 and 174 define
the starting points for the first and last page in the list
of page numbers. Line 176 to 182 basically sets the starting
points in the event that the current page we are browsing is
less that the fluctuation amount, in this case, less than
three. Obviously then, we do not need to print the direct
link to the first page because it is already visible. Line
184 to 188 basically does the same thing on the other side
of the spectrum. Lines 190 to 193 make sure that, should the
minpage variable be less than one, it will never display as
anything but 1, as our first page cannot be 0. Lines 195 to
205 do the same thing for page one and the last page.
Click here for larger image
Figure Five: paginate()
In Figure 5, above, we see the concatenation of strings
that eventually will make up the row of links at the bottom
of the page. Lines 209 to 212 set up the direct link to the
first page, should the current page you are on exceed 4.
Lines 223 to 236 do the same for when your page number is
less than the amount of pages minus four. On line 214 we
start a for() loop that will start at the
minimum set page and loop through to the maximum set page,
linking each page as it prints. Lines 216 to 221 sets up a
nice exception that simply makes sure that the page we are
currently on is not linked at all.
In Conclusion
Our journey has been a long one, but as usual it is the
journey that counts more than the destination. I think we
have a pretty neat looking PHP pagination class here that
can be styled very simply with CSS and modified as need be.
As usual the example above is free to download, use, modify
and enjoy.
Until next time.
About the Author
Marc Steven Plotz is a Senior Software
Developer for a major South African web development company
specializing in the development of enterprise-class web
applications and rapid application development frameworks.
He is also a technical writer for various developer websites
focusing on open source topics like PHP, CSS, HTML and
Javascript. He lives in Pretoria, South Africa, with his
wife and two children.
Resources
classes.php
example.php
|