Here's another old tut, enjoy it before I remake it

Now i'm going to go through how to make an advanced pagination class in PHP.
First thing's first, we need to set up our class:
Code:
<?php
class pagination
{
// our code will go here
}
?>
If you do not know what a class is, or you do not understand them properly, i highly suggest doing a tutorial on classes. They are very useful and knowing how they work is crucial for this tutorial. Try searching for "Object Oriented Programming" in a search engine.
Now we need to set up our class variables. These variables can be used by any function in our class and are more like properties than variables. These go just after the opening curly bracket for the class.
Code:
var $url; // this is the url where the class is being called
var $username; // this is the username of the person viewing the page
var $page; // this is the current page number
var $global_query; // this is the query that is being paginated
Now we have all the variables necessary for this class set up, we will move onto the first function. You may need to adapt the query to suite your needs.
Code:
function rows_per_page()
{
$user = mysql_query("SELECT * FROM `users` WHERE `username` = '$this->username' ORDER BY `id` DESC LIMIT 1");
$num = mysql_num_rows($user);
$fetchuser = mysql_fetch_array($user);
if($num != 1){
return 10; // if viewer is not logged in, return 10
} else {
return $fetchuser['rows_per_page']; // if viewer is logged in, return their prefered rows
}
}
Ok, what this function does is looks at the user table for a category called 'rows_per_page'. This is how many rows the user wants displayed on each page. If the person viewing the page is not logged in, it simply returns '10'. If you do not have a user system or you do not want users to be able to choose how many rows are displayed, get rid of everything in the function and have just 'return 10;'.
Now for the query function. This returns to the page the origional query but with the right limits.
Code:
function query($query)
{
$this->global_query = $query; // this stores the query for later use
// this if statement makes sure the query is safe using a function i will you later
if($this->safety() == true){
$rows = $this->rows_per_page(); // this uses our previous function to get the rows per page
$start = ($rows * ($this->page - 1)); // this works out the start limit for our query
$query = str_replace('XBS', $start, $query); // this replaces 'XBS' with the start value (i will explain the XBS later)
$query = str_replace('XBE', $rows, $query); // this replaces 'XBE' with the end value (i will explain the XBE later)
return $query; // returns the query
} else {
return 'Error'; // this is returned if the query is not safe
}
}
This is a very important function. If you are wondering what the 'XBS' and 'XBE' are, they are to do with how you call this function. I will explain why it done like this later.
The next function is the safety function to see if the query is safe to exectute.
Code:
function safety()
{
$page = $this->page; // gets what page the user is on
$page_safety = is_int((int)$page); // makes sure the page is an integer value
// this stops someone going 'http://www.yoursite.com/section/MALICIOUS CODE HERE/'
// You can put even more safety logic here to make sure that the query is secure
if($page_safety == false){
return false; // returns false if page isn't safe
} else {
return true; // returns true if page is safe
}
}
We now have a function to check safety, it is editable, and you can add more logic to make sure your query is completely safe.
The next small function is used by another function later. What it does is turn the query from a query with limits, to one without limits. This allows us to see the total amount of rows in the query.
Code:
function extract($query){
$query = str_replace(' LIMIT XBS , XBE', '', $query); // remove limits from query
return $query;
}
Now we need a function to get the number of pages the query has.
Code:
function get_num_pages()
{
$query = $this->extract($this->global_query); // takes the limits off the query using our previous function
$num_rows = mysql_num_rows(mysql_query($query)); // this gets the number of rows of the query
$rows_per_page = $this->rows_per_page(); // now we use our old function to get the number of rows per page
if($rows_per_page > 0){
return ceil($num_rows / $rows_per_page);
// simple maths dictates that number of rows divided by rows per page gives you the number of pages
} else {
return false; // if rows per page is less that 1 the function returns false
}
}
Now we will make a small function for diplaying the little box with the page numbers in. You can change this function so the box looks different, but this is what i personally use.
Code:
function box_table($content)
{
echo '<br>
<table class="pageBox">
<tr><td> '.$content.'</td></tr>
</table>';
}
And now we need a function to make sure a certain page exists.
Code:
function page_exists($page){
/* this makes sure that the page number is less than or equal to the total number of pages, is greater than 0 and is an integer */
if($page <= $this->get_num_pages() && $page > 0 && is_int((int)$page)){
return true;
} else {
return false;
}
}
Now for the very last function which works out all the content for inside the box. This is quite long, read all the code comments carefully

One thing i will explain is 'XBP' is in the inputted url ($this->url), I will talk more about that later.
Code:
function box_display(){
$num_pages = $this->get_num_pages(); // gets number of pages
$page = $this->page; // gets current page
$url = $this->url; // gets url of page
$box_content = ''; // makes an empty variable which will be returned at the end after being added to
// if current page is greater than 1
if($page > 1){
$back_url = str_replace('XBP', $page - 1, $url); // replaces XBP with the page number - 1
$box_content .= '<a href='.$back_url.'><</a> '; // adds a back arrow to $box_content
}
// if page - 4 is greater than 1 (this is so we don't repeat putting '1' into $box_content)
if($page - 4 > 1){
$one_url = str_replace('XBP', 1, $url); // replaces XBP with 1
$box_content .= '<a href='.$one_url.'>1</a> '; // adds a link to page 1
}
// if page - 4 > 2 (this is so we can leave a gap between numbers to save space)
if($page - 4 > 2){
$box_content .= '<font color="black">. . . </font>'; // adds '. . .' to $box_content
}
$p = $page - 4; // makes a variable to loop with
// while $p is smaller than $page
while($p < $page){
// if the $p as a page exists
if($this->page_exists($p)){
$p_url = str_replace('XBP', $p, $url); // replaces 'XBP' with the current $p value
$box_content .= '<a href='.$p_url.'>'.$p.'</a> '; // adds a link to page $p in $box_content
}
$p++; // increment $p
}
$box_content .= $page; // displays the current page number
$box_content .= ' '; // adds a space
$x = $page + 1; // $x is 1 more than page
// while $x is smaller than or equal to $page + 4
while($x <= $page + 4){
// if page $x exists
if($this->page_exists($x)){
$x_url = str_replace('XBP', $x, $url); // replaces 'XBP' with current value of $x
$box_content .= '<a href='.$x_url.'>'.$x.'</a> '; // adds a link to page $x in $box_content
}
$x++; // increments $x
}
/* adds a '. . .' if there is a large enough gap between the last value of $x and the last page number */
if($page + 4 < $num_pages - 1){
$box_content .= '<font color="black">. . . </font>';
}
// if $page + 4 is smaller than the page number of the last page
if($page + 4 < $num_pages){
$last_url = str_replace('XBP', $num_pages, $url); // replaces 'XBP' with the page number of the last page
$box_content .= '<a href='.$last_url.'>'.$num_pages.'</a> '; // adds a link to the last page in $box_content
}
// if there is a page above the current page
if($this->page_exists($page + 1)){
$for_url = str_replace('XBP', $page + 1, $url); // replaces 'XBP' with the current page + 1
$box_content .= '<a href='.$for_url.'>></a>'; // adds a link to $box_content to the next page up
}
// if the number of pages isn't 0
if($num_pages != 0){
$this->box_table($box_content); // display a box using the previous function with everything $box_content has in it
}
}
And that's the end of the class. Here is the full code. I have not commented it so when a copy and paster just grabs it, they won't understand why it isn't working

.
You can not copy and paste this - it will not work without your changes.Code:
<?php
class pagination
{
var $url;
var $username;
var $page;
var $global_query;
function rows_per_page()
{
$user = mysql_query("SELECT * FROM `users` WHERE `username` = '$this->username' ORDER BY `id` DESC LIMIT 1");
$num = mysql_num_rows($user);
$fetchuser = mysql_fetch_array($user);
if($num != 1){
return 10;
} else {
return $fetchuser['rows_per_page'];
}
}
function query($query)
{
$this->global_query = $query;
if($this->safety() == true){
$rows = $this->rows_per_page();
$start = ($rows * ($this->page - 1));
$query = str_replace('XBS', $start, $query);
$query = str_replace('XBE', $rows, $query);
return $query;
} else {
return 'Error';
}
}
function safety()
{
$page = $this->page;
$page_safety = is_int((int)$page);
if($page_safety == false){
return false;
} else {
return true;
}
}
function extract($query){
$query = str_replace(' LIMIT XBS , XBE', '', $query);
return $query;
}
function get_num_pages()
{
$query = $this->extract($this->global_query);
$num_rows = mysql_num_rows(mysql_query($query));
$rows_per_page = $this->rows_per_page();
if($rows_per_page > 0){
return ceil($num_rows / $rows_per_page);
} else {
return false;
}
}
function box_table($content)
{
echo '<br>
<table class="pageBox">
<tr><td> '.$content.'</td></tr>
</table>';
}
function page_exists($page){
if($page <= $this->get_num_pages() && $page > 0 && is_int((int)$page)){
return true;
} else {
return false;
}
}
function box_display(){
$num_pages = $this->get_num_pages();
$page = $this->page;
$url = $this->url;
$box_content = '';
if($page > 1){
$back_url = str_replace('XBP', $page - 1, $url);
$box_content .= '<a href='.$back_url.'><</a> ';
}
if($page - 4 > 1){
$one_url = str_replace('XBP', 1, $url);
$box_content .= '<a href='.$one_url.'>1</a> ';
}
if($page - 4 > 2){
$box_content .= '<font color="black">. . . </font>';
}
$p = $page - 4;
while($p < $page){
if($this->page_exists($p)){
$p_url = str_replace('XBP', $p, $url);
$box_content .= '<a href='.$p_url.'>'.$p.'</a> ';
}
$p++;
}
$box_content .= $page; // displays the page number
$box_content .= ' ';
$x = $page + 1;
while($x <= $page + 4){
if($this->page_exists($x)){
$x_url = str_replace('XBP', $x, $url);
$box_content .= '<a href='.$x_url.'>'.$x.'</a> ';
}
$x++;
}
if($page + 4 < $num_pages - 1){
$box_content .= '<font color="black">. . . </font>';
}
if($page + 4 < $num_pages){
$last_url = str_replace('XBP', $num_pages, $url);
$box_content .= '<a href='.$last_url.'>'.$num_pages.'</a> ';
}
if($this->page_exists($page + 1)){
$for_url = str_replace('XBP', $page + 1, $url);
$box_content .= '<a href='.$for_url.'>></a>';
}
if($num_pages != 0){
$this->box_table($box_content);
}
}
}
?>
Now I will explain how to call this class and make it work

For this example, let's pretend we want to paginate some comments on a news post or a picture or something.
First we need to create a new 'pagination' which is our class.
Code:
$comments = new pagination;
Now we enter our variables for the class.
Code:
$comments->url = 'http://www.yoursite.com/section/news_post_3/XBP/';
// notice above there is the 'XBP' I hope you understand now why it's there and how the class uses it to make links
// you will need to input your own user systems username variable for this next line
$comments->username = $username;
// checks that the page variable in the URL (XBP) isn't empty
if(!empty($get['page'])){
$comments->page = $get['page']; // if it isn't, set $comments->page to the current page
} else {
$comments->page = 1; // if it is, set $comments->page equal to 1
}
Now that's done, we have to use the query function in the class to add limits to the query we want to use.
Code:
$query = $comments->query("SELECT * FROM `comments` WHERE `tid` = 'THE ID OF NEWS_POST_3' ORDER BY `id` DESC LIMIT XBS , XBE");
Now, notice in this there is the XBS and the XBE which we used earlier. So all this will do is use the query function to change this query so that it has the right limits.
The end bit must be written exactly like 'LIMIT XBS , XBE' or it will not work!You also need to change the 'THE ID OF NEWS_POST_3' to a variable which contains the id of whatever news post you are on.
If you look further up to where I defined the url for the class, you will see 'news_post_3' again. This should actually be just a variable. The same variable for the query, and the url.
Now we can execute the query because it has the right limits.
Code:
$comment_list = mysql_query($query) // executes the query;
$count_comments = mysql_num_rows($comment_list); // checks number of rows returned
Now we will display the comments.
Code:
// if number of rows == 0
if($count_comments == 0){
echo 'Sorry, there are no comments yet!';
} else {
// makes a loop to display the comments
while($c = mysql_fetch_array($comment_list)){
echo $c['comment_message'];
}
// now we can display the box aswell
$comments->box_display();
}
And that's it!
Thanks for reading, please subscribe or register

All comments appreciated.
Carnage
Note: This tutorial (and the class code) is copyrighted by Noobic 2009, it can be indexed but you cannot copy and paste it! You can use the class code for your websites, but do not put it in your tutorials.