Organizing articles into pages

Published 24. Sep 2010, 23:58
Files fnc_pageLister.php

In any kind of system where you have a lot of information, you often find yourself in a situation where you want to divide it into smaller, more user friendly pieces. Take a book for example. A book's content could very well be on one very very big sheet of paper or it could be organized into pages. The same principle goes for websites.

This article has one or more followup articles: PageLister - Simple pagination for array collections

There's many ways to implement pages and your immideate needs may differ, therefore this is not an alpha-o-mega. Still the basic principles are the same, so let's get on with it.

What you need:
  • Ability to set and retrieve the current page number. This could be done by adding a fixed named parameter in the url (ie. mypage.php?page=1).
  • Define how many items per page you want to show.
  • Access to the collection of items and the ability to slice out the items for the current page. You also need to know the maximium amount of items in the collection.

Now you are able to calculate the maximum amount of pages and with the current page and items per page numbers also the slice offset and length of the collection. A rough implementation could look something like this:

// get the current page number, default is 1
$page = !empty($_GET['page']) ? (int) $_GET['page'] : 1;

// we assign some dummy items
$allItems = array();
for ($i=0; $i<25; $i++) $allItems[] = $i;

$itemsPerPage = 5;

// calculate max number of pages
$numPages = ceil(count($allItems)/$itemsPerPage);

// get the current page items (slice the collection)
$currentPageItems = array_slice($allItems, ($page-1)*$itemsPerPage, $itemsPerPage);

// output current page items
echo "Current page items:<br />\n";

foreach ($currentPageItems as $v)
	echo $v."<br />\n";

// output page list
echo "Pages: \n";

for ($i=1; $i<=$numPages; $i++)
    echo "<a href='?page=$i'>$i</a> \n";

The code above will output something like this:

Current page items:
Pages: 1 2 3 4 5
Current page items:<br />
0<br />
1<br />
2<br />
3<br />
4<br />
<a href='?page=1'>1</a>
<a href='?page=2'>2</a>
<a href='?page=3'>3</a>
<a href='?page=4'>4</a>
<a href='?page=5'>5</a>

Now if we were to follow the link to page 5, we would show the last 5 items instead of the first 5. It would look like this:

Current page items:
Pages: 1 2 3 4 5

I guess you got the idea by now. Now wouldn't it be great if we could wrap all of this code into something. Luckily I've implemented a generic function to handle this sort of thing, the pageLister(). I'm now going to replicate the first implementation, but this time I'll be using the pageLister() function.

You will see some new variables in this snippet. $pageList is an associative array containing all the page numbers. If the fifth argument is given (which it is in this example) the array keys will be formatted with the given string. The given string should be an url containing the replacement argument (%d) for the page number. You can see the formatted url being used in the $url variable in the bottom of the snippet.

$allItems = array();
for ($i=0; $i<25; $i++) $allItems[] = $i;

$page = !empty($_GET['page']) ? (int) $_GET['page'] : 1;

 * The first argument is the collection, the second is the current page number, 
 * the third is items per page, fourth is the page list passed by reference and
 * the fifth optional argument is the string used to format the urls.
$currentPageItems = pageLister($allItems, $page, 5, $pageList, '?page=%d');

echo "Current page items: <br />\n";

foreach ($currentPageItems as $v)
	echo $v."<br />\n";

echo "Pages: \n";
// here we use the formatted urls
foreach ($pageList as $url => $page)
	echo "<a href='$url'>$page</a> \n";

// note that nothing hinders you from doing this instead:
foreach ($pageList as $page)
	echo "<a href='?page=$page'>$page</a> \n";

Now you should be able to implement this in your own setting. Enjoy.


View Source: fnc_pageLister.php
Download: fnc_pageLister.php

Back to the top