<?php
/**
 * a simple navigation, without
 * too much characters, so your
 * layout won't be screwed
 * @param    string    page_url
 * @param    integer   total
 * @param    integer   limit
 * @return   string
 * @author   JeXuS <jexus@jexus.net>
**/
function navigation ($page_url, $total, $limit)
{
	// use sprintf, so you can easily edit this
	static $href = '<a href="%s">%s<a> ';
	// parameter used in url
	static $param = 'page';
	$param_preg = preg_quote ($param);

	// erase (&|?)page from the url (for extra security use a while)
	while (preg_match ('|[?&]' . $param_preg . '=[^&]*|i', $page_url))
	{
		// if it matches, replace it with nothing
		$page_url = preg_replace ('|[?&]' . $param_preg . '=[^&]*|i', '', $page_url);
	}
	// check if we have a correct URI (if it doesn't have a ?, we should replace 1 & with ?
	$page_url = (strpos ($page_url, '?') !== false) ? $page_url : preg_replace ('~&~', '?', $page_url, 1);
	// check if we have a '?', if so, the seperator is '&amp;'
	$seperator = (strpos ($page_url, '?') !== false) ? '&amp;' : '?';

	// the total pages
	$pages = ceil ($total / $limit);
	// check if the parameter was set
	$curr = (isset ($_GET[$param])) ? $_GET[$param] : 1;
	// check if the current page isn't too high or low
	$curr = ($curr < 1) ? 1 : (($curr > $pages) ? $pages : $curr);
	// check the middle, we always need 3 parts, so current might be too low
	$middle = ($curr < 7 || $curr > ($pages - 7)) ? round ($pages / 2) : false;
	// if the check wasn't false, create an array 'in the middle'
	$middle = ($middle !== false) ? array_keys (array_fill ($middle - 2, 4, '')) : array ();
	// create an array of integers we'll need
	$show = array_merge (
		array_keys (array_fill (0, 4, '')), // first set
		array_keys (array_fill ($curr - 2, 4, '')), // current set
		$middle, // middle set
		array_keys (array_fill ($pages - 4, 4, '')) // final set
	);
	// erase the doubles
	$show = array_unique ($show);
	// do a natural sort (1 2 3 etc.)
	// normally would be 1 10 11 etc.
	natsort ($show);

	// initialise for E_NOTICE error
	$return = '';
	// another init
	$prev = 1;
	// prev link
	$return .= ($curr > 1) ? sprintf ($href, $page_url . $seperator . $param . '=' . ($curr - 1), '&laquo;') : '';
	// loop through the pages
	foreach ($show as $page)
	{
		// update the page (pages like 1 to 10,
		//  not 0 to 9)
		$page += 1;
		// if it isn't out of bounds
		if ($page <= $pages && $page > 0)
		{
			// check if there's an open space
			if ($prev < $page - 1)
			{
				// if so, seperate nicely
				$return .= ' ... ';
			}
			// update prev counter
			$prev = $page;
			// append to the return string, check if it's the current page, otherwise a link
			$return .= ($page == $curr) ? "<b>{$page}</b> " : sprintf ($href, $page_url . $seperator . $param . '=' . $page, $page);
		}
	}
	// next link
	$return .= ($curr < $pages) ? sprintf ($href, $page_url . $seperator . $param . '=' . ($curr + 1), '&raquo;') : '';
	// return trimmed
	return rtrim ($return);
}

// voorbeeld:
echo navigation ($_SERVER['REQUEST_URI'], 50, 5);
?>