PHP Next and Previous Buttons for Search Query Results

What we’re talking about today is how to make those Next, Previous, and Number buttons for search results…

search results php

Usually found at the bottom of sites like Google and eBay. There’s two pieces of data we need:

  1. Start At / Offset Value (usually set in the URL)
  2. Limit (set internally or in the URL)

Being we only need these two variables, you might think this is a pretty simple task, but creating some well-working links takes a fair bit of code. For this example, we’ll define the limit internally, but still use dynamic code so it could be used as a GET variable.

The first issue we have in defining links to a different offset is in the URL itself:

index.php?keywords=tampawebsitedesign&start_at=10&order_by=1

As you can see here, our start_at variable is equal to 10, which is what we’ll put in our sql string. The problem is when they hit the next page button that sets it to 20. This impacts your links because you have to securely redefine the offset variable without loosing the other variables. Here’s how we would do that:

// get the current URL
$current_url = (!empty($_SERVER['HTTPS'])) ? "https://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'] : "http://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
// replace the start_at variable and value
$pattern = '/\&start_at=[0-9]*/';
$back_forward_url = preg_replace($pattern,'',$current_url);

Here we’ve basically stripped our start_at variable and value from the URL. Moving forward, we need to generate our Next and Previous buttons. This part is pretty simple:

$start_at = $_GET['start_at']; // set the start_at variable equal to the URL value
$limit_num = 10; // set the limit equal to 10 (or whatever you want)
 
// calculate the previous amount and link
$previous_amt = $start_at - $limit_num;
$previous_link = '<a href="'.$back_forward_url.'&start_at='.$previous_amt.'">Previous</a>';
 
// calculate the next amount and link 
$next_amt = $start_at + $limit_num;
$next_link = '<a href="'.$back_forward_url.'&start_at='.$next_amt.'">Next</a>';
 
// if statements which set the links equal to nothing
if ($start_at == '0')
{
	$previous_link = '';
}
if (($start_at + $limit_num) >= $total_results)
{
	$next_link = '';
}

At this point we have our Next and Previous button variables taken care of. Now we need to make the numbers in the middle. Something to note, however, is that if you have 100 pages of results returned, we don’t want to print out 100 numbers, we only want to print out 9 or 10 or around there. So we need to install a range of if statements that will make sure we put in the right amount.

The first step is to create a function which our total pages and current page can calculate from:

// shared function for calculations
function find_page($tr,$ln)
{
	$pages_total = intval($tr / $ln) +1; // intval rounds any decimal down to its integer value
	$match_results = ($pages_total -1) * $ln;
	if ($match_results == $tr) {$pages_total--; }
	return $pages_total;
}
// find total pages
$pages_total = find_page($total_results,$limit_num);
 
// find current page
$curr_page = find_page($start_at,$limit_num) + 1;

Next, we put in our if statements to set two new variables: $page_link and $loop.

 
if ($pages_total < 9)
{
	$page_link = 1;
	$loop = $pages_total + 1;
}
else if ($curr_page + 4 > $pages_total)
{
	$page_link = $pages_total - 8;
	$loop = 10;
}
else 
{
	if ($curr_page < 9)
	{
		$page_link = 1;
		$loop = 10;
	}
	else 
	{
		$page_link = $curr_page - 4;
		$loop = 10;
	}
}

Just about done! Now, we’ll loop through and save our links to a variable called $middle_links. I’ve taken the extra step to add in a styling class for an active link versus a non-active link.

for ($i=1;$i<$loop;$i++)
{
	$page_start_at = ($page_link * $limit_num) - $limit_num;
	if ($curr_page==$page_link){;$link_class='page_btn_active';}else{$link_class='page_btn';}
	$middle_links .= '<a href="'.$back_forward_url.'&start_at='.$page_start_at.'" class="'.$link_class.'">'.$page_link.'</a> | ';
	$page_link++;
}

Finally, we’ll put everything together and print it out. We have to do one last check before our print which is taking off the extra ” | ” from our loop if there is no Next button. You can also see that we’ve added a div to style the entire link bar.

if ($next_link==''){
	$middle_links = substr($middle_links,0,-3); // take out the extra " | " if we have no Next button
}
 
print '<div id="page_link_bar">'.$previous_link.' '.$middle_links.' '.$next_link.'</div>'; // put everything together

There you have it!

Some hints to help you along as well:

  • If the start_at value is not set in the URL, you need to set that to 0
  • Always do verification on your REQUEST (GET & POST) variables. is_numeric() function works well for the start_at variable.
  • To make it work, you’ll just append your variables into your MySQL statement using LIMIT.
    SELECT * WHERE id=1 ORDER BY id DESC LIMIT $start_at,$limit_num

About the Author