PEAR::Pager Tutorials - Create pretty links with Pager and mod_rewrite

Most PHP pager classes can work just fine with GET parameters, correctly forwarding them through the pages. Few of them let you control the navigation links they create, though. This can be particularly annoying when you have some nice urls (thanks to some mod_rewrite rules o to your hand-crafted front controller) and the pager class can't respect them, showing the real, ugly links to the world.
If the above scenario is not new to you, then you should probably have a look at PEAR::Pager. It's a fully customizable package that should satisfy all your needs, including your preferred link format.

Example: How to tell Pager about your links format

Let's suppose you have an online eCommerce site, with a product catalog the user can browse by category. For instance, to list all the products of the category AAA, you pass that parameter to your page: http://myserver.com/products.php?cat=AAA.
If the catalog is large enough, splitting the products into pages would be a sensible decision, but now you also have to pass the page number to the URL: http://myserver.com/products.php?cat=AAA&pageID=3.
Of course your clever application can produce cleaner urls, like this: /products/AAA/3.html which are easily decoded by mod_rewrite.
Let's see the sample .htaccess rule for this url transformation:

RewriteEngine on
 
RewriteBase /
RewriteRule ^products/(\w+)/(\d+)\.html$ /products.php?cat=$1&pageID=$2 [L]

Normally, the pager class would get the cat and pageID parameters and build the links in the usual way, i.e.

/products.php?cat=AAA&pageID=1
/products.php?cat=AAA&pageID=2
...
/products.php?cat=AAA&pageID=6

but you can educate PEAR::Pager to produce links that respect your convention:

<?php
require_once 'Pager/Pager.php';

//always validate the GET parameters
if (!empty($_GET['cat']) && $myApp->is_valid_cat($_GET['cat'])) {
    $cat = $_GET['cat'];
} else {
    $cat = 'AAA'; //default category
}

//fetch the products. If there are many products,
// you may consider using the Pager_Wrapper functions
$products = $myApp->getProductsByCat($cat);

$pager_params = array(
    'mode'     => 'Sliding',
    'append'   => false,  //don't append the GET parameters to the url
    'path'     => 'http://myserver.com/products/' . $cat,
    'fileName' => '%d.html',  //Pager replaces "%d" with the page number
    'perPage'  => 10, //show 10 articles per page
    'itemData' => $products,
);
$pager = & Pager::factory($pager_params);
$data  = $pager->getPageData();

//print the products for the current page
echo 'Data for current page: ';
print_r($data);

//show the navigation links for the current category
echo $pager->links;
?>

As you can see, you can tell Pager about the path and fileName it should use. Don't forget to set the append option to FALSE, otherwise Pager will try to append the GET vars to the url in the usual way.

Example #2: page number in the path and not in the file name?

What if the pager number in your url scheme is in the path and not in the file name? It might look like a problem, since Pager looks for the "%d" string in the fileName parameter, and it complains if it can't find that string there. No, you can't put it in the path parameter, but since Pager will simply combine the path and fileName parameters to form the url, we can trick it and put a part of the path in the filename itself.
For instance, if we have an url like http://myserver.com/products/AAA/3/index.html, where "3" is the page number, here's the mod_rewrite rule and the php script to make it working:

RewriteEngine on
 
RewriteBase /
RewriteRule ^products/(\w+)/(\d+)/index\.html$ /products.php?cat=$1&pageID=$2 [L]
<?php
require_once 'Pager/Pager.php';

// ...

$pager_params = array(
    'mode'     => 'Sliding',
    'append'   => false,  //don't append the GET parameters to the url
    'path'     => 'http://myserver.com/products/' . $cat,
    'fileName' => '%d/index.html',  //Pager replaces "%d" with the page number
    'perPage'  => 10, //show 10 articles per page
    'itemData' => $products,
);
$pager = & Pager::factory($pager_params);
$data  = $pager->getPageData();

//print the products for the current page
echo 'Data for current page: ';
print_r($data);

//show the navigation links for the current category
echo $pager->links;
?>

That's it. I hope this tutorial was useful. Keep tuned, more to come.

« Go back to PEAR::Pager tutorials index.

PEAR Pager Tutorials - Lorenzo Alberton




2 responses to "PEAR::Pager Tutorials - Create pretty links with Pager and mod_rewrite"

perfect! exactly what I needed .... thank you

useful information for me thanks

Lorenzo Alberton

Lorenzo Alberton Lorenzo PHP5 ZCE - Zend Certified Engineer has been working with large enterprise UK companies for the past years and is now Chief Tech Architect at DataSift. He's an international conference speaker and a long-time contributor to many open source projects. Lorenzo Alberton's profile on LinkedIN View Lorenzo Alberton's Twitter stream

Lorenzo Alberton - Sun Certified MySQL 5 Developer

Tags

AJAX, Apache, Book Review, Charset, Cheat Sheet, Data structures, Database, Firebird SQL, Hadoop, Imagick, INFORMATION_SCHEMA, JavaScript, Kafka, Linux, Message Queues, mod_rewrite, Monitoring, MySQL, NoSQL, Oracle, PDO, PEAR, Performance, PHP, PostgreSQL, Profiling, Scalability, Security, SPL, SQL Server, SQLite, Testing, Tutorial, TYPO3, Windows, Zend Framework

Buy me a book - Applied Mathematics For Database Professionals