PHP Pagination – Two small tweaks

Background

PHP and MySQL are very powerful. I had a web site with roughly 100,000 rows coming from the joining of three tables that would take at least a few seconds to be output to the web browser and displayed to the end user. The delay was noticeable.
There seemed to be two solutions, either look into ways that will speed up the processing, such as caching, or reduce the amount of output. Given the nature of the product, reducing the output made the most sense and using pagination seemed ideal.
In searching for guides on best practices for using PHP pagination of MySQL content, I found a few great ones, linked at the end under Sources.

Issues

While the guides were great, I had three concerns. First, when there are many pages, being able to quickly move to the first and last page can be important, rather than slowly clicking each page one at a time. Second, I wanted to ensure that the code being executed was efficient, as it will be executed on each page load. Third, when using $_SERVER[‘PHP_SELF’], I wanted to prevent any type of XSS or other exploit.

Solutions

For navigation, I added a link for the first page and the last page that appear whenever the user is on any page above page 6 or below 5 pages from the last page. There is an added convenience in allowing the user to quickly and easily jump to the first or last page.

if ($page_number > 6) {
    $paginationCtrls .= '<a href="' . $_SERVER['PHP_SELF'] . '/page/1">1</a> nbsp; ... nbsp; ';
}
if ($page_number < $last_page - 5) {
    $paginationCtrls .= ' ...   <a href="' . $_SERVER['PHP_SELF'] . '/page/' . $last_page . '">' . $last_page . '</a> nbsp; ';
}

Also available in a gist on GitHub: https://gist.github.com/joeykrim/3ef874119a0fbed7b90b

For looking at code efficiency, there were two sections of for loops that were looping over numbers which were not being used based on the inside if statement. By changing the for loop, not only did it save looping over under-needed numbers, but it also allowed the inside if statement to be removed. Both examples below:
Before

for($i = $pagenum-4; $i < $pagenum; $i++){
    if($i > 0){
        $paginationCtrls .= '<a href="'.$_SERVER['PHP_SELF'].'?pn='.$i.'">'.$i.'</a> nbsp; ';
    }
}

After

for ($i = max($page_number - 4, 1); $i < $page_number; $i++) {
    $paginationCtrls .= '<a href="' . $_SERVER['PHP_SELF'] . '/page/' . $i . '">' . $i . '</a> nbsp; ';
}

Before

for($i = $pagenum+1; $i < = $last; $i++){
	$paginationCtrls .= '<a href="'.$_SERVER['PHP_SELF'].'?pn='.$i.'">'.$i.'</a> nbsp; ';
	if($i >= $pagenum+4){
		break;
	}
}

After

for ($i = $page_number + 1; $i < = min($last_page, $page_number + 4); $i++) {
        $paginationCtrls .= '<a href="' . $_SERVER['PHP_SELF'] . '/page/' . $i . '">' . $i . '</a> nbsp; ';
}

Also available in a gist on GitHub: https://gist.github.com/joeykrim/ba58ae2f82d586523786

Third, while the function $_SERVER[‘PHP_SELF’] is very useful for determining the URL that was used for the currently displayed page, it is taking the input directly from the user’s web browser, and therefore the user. Whenever user input is handled in PHP, it is best to sanitize that input and using a function, such as htmlspecialchars, is one solution.

Final Output Example

php_pagination_example

Source

https://www.developphp.com/video/PHP/Pagination-MySQLi-Google-Style-Paged-Results-Tutorial
http://www.onlinetuting.com/pagination-in-php-mysqli/
http://stackoverflow.com/questions/10272282/how-to-secure-serverphp-self

Leave a Reply

Your email address will not be published. Required fields are marked *

*