Skip to content

Instantly share code, notes, and snippets.

@johnsardine
Last active December 26, 2015 18:29
Show Gist options
  • Save johnsardine/7195283 to your computer and use it in GitHub Desktop.
Save johnsardine/7195283 to your computer and use it in GitHub Desktop.
PHP Pagination, estracted from CodeIgniter and simplified
<?php
if (!function_exists('http_build_url')) {
define('HTTP_URL_REPLACE', 1); // Replace every part of the first URL when there's one of the second URL
define('HTTP_URL_JOIN_PATH', 2); // Join relative paths
define('HTTP_URL_JOIN_QUERY', 4); // Join query strings
define('HTTP_URL_STRIP_USER', 8); // Strip any user authentication information
define('HTTP_URL_STRIP_PASS', 16); // Strip any password authentication information
define('HTTP_URL_STRIP_AUTH', 32); // Strip any authentication information
define('HTTP_URL_STRIP_PORT', 64); // Strip explicit port numbers
define('HTTP_URL_STRIP_PATH', 128); // Strip complete path
define('HTTP_URL_STRIP_QUERY', 256); // Strip query string
define('HTTP_URL_STRIP_FRAGMENT', 512); // Strip any fragments (#identifier)
define('HTTP_URL_STRIP_ALL', 1024); // Strip anything but scheme and host
// Build an URL
// The parts of the second URL will be merged into the first according to the flags argument.
//
// @param mixed (Part(s) of) an URL in form of a string or associative array like parse_url() returns
// @param mixed Same as the first argument
// @param int A bitmask of binary or'ed HTTP_URL constants (Optional)HTTP_URL_REPLACE is the default
// @param array If set, it will be filled with the parts of the composed url like parse_url() would return
function http_build_url($url, $parts=array(), $flags=HTTP_URL_REPLACE, &$new_url=false)
{
$keys = array('user', 'pass', 'port', 'path', 'query', 'fragment');
// HTTP_URL_STRIP_ALL becomes all the HTTP_URL_STRIP_Xs
if ($flags & HTTP_URL_STRIP_ALL) {
$flags |= HTTP_URL_STRIP_USER;
$flags |= HTTP_URL_STRIP_PASS;
$flags |= HTTP_URL_STRIP_PORT;
$flags |= HTTP_URL_STRIP_PATH;
$flags |= HTTP_URL_STRIP_QUERY;
$flags |= HTTP_URL_STRIP_FRAGMENT;
}
// HTTP_URL_STRIP_AUTH becomes HTTP_URL_STRIP_USER and HTTP_URL_STRIP_PASS
else if ($flags & HTTP_URL_STRIP_AUTH) {
$flags |= HTTP_URL_STRIP_USER;
$flags |= HTTP_URL_STRIP_PASS;
}
// Parse the original URL
$parse_url = parse_url($url);
// Scheme and Host are always replaced
if (isset($parts['scheme']))
$parse_url['scheme'] = $parts['scheme'];
if (isset($parts['host']))
$parse_url['host'] = $parts['host'];
// (If applicable) Replace the original URL with it's new parts
if ($flags & HTTP_URL_REPLACE) {
foreach ($keys as $key) {
if (isset($parts[$key]))
$parse_url[$key] = $parts[$key];
}
}
else {
// Join the original URL path with the new path
if (isset($parts['path']) && ($flags & HTTP_URL_JOIN_PATH)) {
if (isset($parse_url['path']))
$parse_url['path'] = rtrim(str_replace(basename($parse_url['path']), '', $parse_url['path']), '/') . '/' . ltrim($parts['path'], '/');
else
$parse_url['path'] = $parts['path'];
}
// Join the original query string with the new query string
if (isset($parts['query']) && ($flags & HTTP_URL_JOIN_QUERY)) {
if (isset($parse_url['query']))
$parse_url['query'] .= '&' . $parts['query'];
else
$parse_url['query'] = $parts['query'];
}
}
// Strips all the applicable sections of the URL
// Note: Scheme and Host are never stripped
foreach ($keys as $key) {
if ($flags & (int)constant('HTTP_URL_STRIP_' . strtoupper($key)))
unset($parse_url[$key]);
}
$new_url = $parse_url;
return
((isset($parse_url['scheme'])) ? $parse_url['scheme'] . '://' : '')
.((isset($parse_url['user'])) ? $parse_url['user'] . ((isset($parse_url['pass'])) ? ':' . $parse_url['pass'] : '') .'@' : '')
.((isset($parse_url['host'])) ? $parse_url['host'] : '')
.((isset($parse_url['port'])) ? ':' . $parse_url['port'] : '')
.((isset($parse_url['path'])) ? $parse_url['path'] : '')
.((isset($parse_url['query'])) ? '?' . $parse_url['query'] : '')
.((isset($parse_url['fragment'])) ? '#' . $parse_url['fragment'] : '')
;
}
}
/**
* Looks in an url for a query parameter and replaces it or creates if it does not exist
*
* @access public
* @param mixed $key
* @param mixed $value
* @param mixed $url
* @return void
*/
function push_param($key, $value, $url)
{
// Parse url
$url = parse_url($url);
// Prepopulate query string
$url_params = array();
if (!empty($url['query'])) {
parse_str($url['query'], $url_params);
}
// Push/change value
$url_params[$key] = $value;
// Build query string and replace current
$url['query'] = http_build_query($url_params);
// Output changed url
return http_build_url('', $url);
}
function remove_param($key, $url)
{
// Parse url
$url = parse_url($url);
// Prepopulate query string
$url_params = array();
if (!empty($url['query'])) {
parse_str($url['query'], $url_params);
}
// Remove parameter
unset($url_params[$key]);
// Build query string and replace current
$url['query'] = http_build_query($url_params);
// If no url parameters, unset query
if (empty($url_params))
unset($url['query']);
// Output changed url
return http_build_url('', $url);
}
<?php
class Pagination {
var $base_url = ''; // The page we are linking to
var $prefix = 'page'; // A custom prefix added to the path.
var $suffix = ''; // A custom suffix added to the path.
var $total_rows = 0; // Total number of items (database results)
var $per_page = 10; // Max number of items you want shown per page
var $num_links = 2; // Number of "digit" links to show before/after the currently viewed page
var $cur_page = 0; // The current page being viewed
var $use_page_numbers = TRUE; // Use page number for segment instead of offset
var $uri_segment = '';
var $page = '';
var $first_url = ''; // Alternative URL for the First Page.
var $page_query_string = TRUE;
var $query_string_segment = 'per_page';
var $display_pages = TRUE;
var $anchor_class = '';
var $first_link = '&lsaquo; First';
var $last_link = 'Last &rsaquo;';
var $next_link = '&gt;';
var $prev_link = '&lt;';
var $full_tag_open = '<ul class="pagination">';
var $full_tag_close = '</ul>';
var $first_tag_open = '<li class="pp-first">';
var $first_tag_close = '</li>';
var $last_tag_open = '<li class="pp-last">';
var $last_tag_close = '</li>';
var $cur_tag_open = '<li class="pp-current"><a href=""><span>';
var $cur_tag_close = '</span></a></li>';
var $next_tag_open = '<li class="pp-next">';
var $next_tag_close = '</li>';
var $prev_tag_open = '<li class="pp-prev">';
var $prev_tag_close = '</li>';
var $num_tag_open = '<li class="pp-num">';
var $num_tag_close = '</li>';
// var $base_url = ''; // The page we are linking to
// var $prefix = ''; // A custom prefix added to the path.
// var $suffix = ''; // A custom suffix added to the path.
//
// var $total_rows = 0; // Total number of items (database results)
// var $per_page = 10; // Max number of items you want shown per page
// var $num_links = 2; // Number of "digit" links to show before/after the currently viewed page
// var $cur_page = 0; // The current page being viewed
// var $use_page_numbers = FALSE; // Use page number for segment instead of offset
// var $first_link = '&lsaquo; First';
// var $next_link = '&gt;';
// var $prev_link = '&lt;';
// var $last_link = 'Last &rsaquo;';
// var $uri_segment = 4;
// var $full_tag_open = '';
// var $full_tag_close = '';
// var $first_tag_open = '';
// var $first_tag_close = '&nbsp;';
// var $last_tag_open = '&nbsp;';
// var $last_tag_close = '';
// var $first_url = ''; // Alternative URL for the First Page.
// var $cur_tag_open = '&nbsp;<strong>';
// var $cur_tag_close = '</strong>';
// var $next_tag_open = '&nbsp;';
// var $next_tag_close = '&nbsp;';
// var $prev_tag_open = '&nbsp;';
// var $prev_tag_close = '';
// var $num_tag_open = '&nbsp;';
// var $num_tag_close = '';
// var $page_query_string = FALSE;
// var $query_string_segment = 'per_page';
// var $display_pages = TRUE;
// var $anchor_class = '';
/**
* Constructor
*
* @access public
* @param array initialization parameters
*/
public function __construct($params = array())
{
if (count($params) > 0)
{
$this->initialize($params);
}
if ($this->anchor_class != '')
{
$this->anchor_class = 'class="'.$this->anchor_class.'" ';
}
$this->base_url = base_url(path_info());
$this->first_url = remove_param('page', base_url(path_info()));
}
// --------------------------------------------------------------------
/**
* Initialize Preferences
*
* @access public
* @param array initialization parameters
* @return void
*/
function initialize($params = array())
{
if (count($params) > 0)
{
foreach ($params as $key => $val)
{
if (isset($this->$key))
{
$this->$key = $val;
}
}
}
// If no page is defined, fallback to uri_segment
$this->page = (!empty($this->uri_segment)) ? $this->uri_segment : $this->page;
}
// --------------------------------------------------------------------
/**
* Generate the pagination links
*
* @access public
* @return string
*/
function create_links()
{
// If our item count or per-page total is zero there is no need to continue.
if ($this->total_rows == 0 OR $this->per_page == 0)
{
return '';
}
// Calculate the total number of pages
$num_pages = ceil($this->total_rows / $this->per_page);
// Is there only one page? Hm... nothing more to do here then.
if ($num_pages == 1)
{
return '';
}
// Set the base page index for starting page number
if ($this->use_page_numbers)
{
$base_page = 1;
}
else
{
$base_page = 0;
}
if ($this->page != $base_page)
{
$this->cur_page = $this->page;
// Prep the current page - no funny business!
$this->cur_page = (int) $this->cur_page;
}
// Set current page to 1 if using page numbers instead of offset
if ($this->use_page_numbers AND $this->cur_page == 0)
{
$this->cur_page = $base_page;
}
$this->num_links = (int)$this->num_links;
if ($this->num_links < 1)
{
//show_error('Your number of links must be a positive number.');
}
if ( ! is_numeric($this->cur_page))
{
$this->cur_page = $base_page;
}
// Is the page number beyond the result range?
// If so we show the last page
if ($this->use_page_numbers)
{
if ($this->cur_page > $num_pages)
{
$this->cur_page = $num_pages;
}
}
else
{
if ($this->cur_page > $this->total_rows)
{
$this->cur_page = ($num_pages - 1) * $this->per_page;
}
}
$uri_page_number = $this->cur_page;
if ( ! $this->use_page_numbers)
{
$this->cur_page = floor(($this->cur_page/$this->per_page) + 1);
}
// Calculate the start and end numbers. These determine
// which number to start and end the digit links with
$start = (($this->cur_page - $this->num_links) > 0) ? $this->cur_page - ($this->num_links - 1) : 1;
$end = (($this->cur_page + $this->num_links) < $num_pages) ? $this->cur_page + $this->num_links : $num_pages;
// Is pagination being used over GET or POST? If get, add a per_page query
// string. If post, add a trailing slash to the base URL if needed
// $this->base_url = rtrim($this->base_url, '/') .'/';
// And here we go...
$output = '';
// Render the "First" link
if ($this->first_link !== FALSE AND $this->cur_page > ($this->num_links + 1))
{
$first_url = ($this->first_url == '') ? $this->base_url : $this->first_url;
$output .= $this->first_tag_open.'<a '.$this->anchor_class.'href="'.$first_url.'"><span>'.$this->first_link.'</span></a>'.$this->first_tag_close;
}
// Render the "previous" link
if ($this->prev_link !== FALSE AND $this->cur_page != 1)
{
if ($this->use_page_numbers)
{
$i = $uri_page_number - 1;
}
else
{
$i = $uri_page_number - $this->per_page;
}
if ($i == 0 && $this->first_url != '')
{
$output .= $this->prev_tag_open.'<a '.$this->anchor_class.'href="'.$this->first_url.'"><span>'.$this->prev_link.'</span></a>'.$this->prev_tag_close;
}
else
{
$link = ($i == 0 || $i == 1) ? remove_param('page', $this->base_url) : push_param($this->prefix, $i, $this->base_url);
$output .= $this->prev_tag_open.'<a '.$this->anchor_class.'href="'.$link.'"><span>'.$this->prev_link.'</span></a>'.$this->prev_tag_close;
}
}
// Render the pages
if ($this->display_pages !== FALSE)
{
// Write the digit links
for ($loop = $start -1; $loop <= $end; $loop++)
{
if ($this->use_page_numbers)
{
$i = $loop;
}
else
{
$i = ($loop * $this->per_page) - $this->per_page;
}
if ($i >= $base_page)
{
if ($this->cur_page == $loop)
{
$output .= $this->cur_tag_open.$loop.$this->cur_tag_close; // Current page
}
else
{
$n = ($i == $base_page) ? '' : $i;
if ($n == '' && $this->first_url != '')
{
$output .= $this->num_tag_open.'<a '.$this->anchor_class.'href="'.$this->first_url.'"><span>'.$loop.'</span></a>'.$this->num_tag_close;
}
else
{
$link = push_param($this->prefix, $n, $this->base_url);
$output .= $this->num_tag_open.'<a '.$this->anchor_class.'href="'.$link.'"><span>'.$loop.'</span></a>'.$this->num_tag_close;
}
}
}
}
}
// Render the "next" link
if ($this->next_link !== FALSE AND $this->cur_page < $num_pages)
{
if ($this->use_page_numbers)
{
$i = $this->cur_page + 1;
}
else
{
$i = ($this->cur_page * $this->per_page);
}
$link = push_param($this->prefix, $i, $this->base_url);
$output .= $this->next_tag_open.'<a '.$this->anchor_class.'href="'.$link.'"><span>'.$this->next_link.'</span></a>'.$this->next_tag_close;
}
// Render the "Last" link
if ($this->last_link !== FALSE AND ($this->cur_page + $this->num_links) < $num_pages)
{
if ($this->use_page_numbers)
{
$i = $num_pages;
}
else
{
$i = (($num_pages * $this->per_page) - $this->per_page);
}
$link = push_param($this->prefix, $i, $this->base_url);
$output .= $this->last_tag_open.'<a '.$this->anchor_class.'href="'.$link.'"><span>'.$this->last_link.'</span></a>'.$this->last_tag_close;
}
// Kill double slashes. Note: Sometimes we can end up with a double slash
// in the penultimate link so we'll kill all double slashes.
// $output = preg_replace("#([^:])//+#", "\\1/", $output);
// Add the wrapper HTML if exists
$output = $this->full_tag_open.$output.$this->full_tag_close;
return $output;
}
}
<?php
if (!function_exists('http_build_url')) {
define('HTTP_URL_REPLACE', 1); // Replace every part of the first URL when there's one of the second URL
define('HTTP_URL_JOIN_PATH', 2); // Join relative paths
define('HTTP_URL_JOIN_QUERY', 4); // Join query strings
define('HTTP_URL_STRIP_USER', 8); // Strip any user authentication information
define('HTTP_URL_STRIP_PASS', 16); // Strip any password authentication information
define('HTTP_URL_STRIP_AUTH', 32); // Strip any authentication information
define('HTTP_URL_STRIP_PORT', 64); // Strip explicit port numbers
define('HTTP_URL_STRIP_PATH', 128); // Strip complete path
define('HTTP_URL_STRIP_QUERY', 256); // Strip query string
define('HTTP_URL_STRIP_FRAGMENT', 512); // Strip any fragments (#identifier)
define('HTTP_URL_STRIP_ALL', 1024); // Strip anything but scheme and host
// Build an URL
// The parts of the second URL will be merged into the first according to the flags argument.
//
// @param mixed (Part(s) of) an URL in form of a string or associative array like parse_url() returns
// @param mixed Same as the first argument
// @param int A bitmask of binary or'ed HTTP_URL constants (Optional)HTTP_URL_REPLACE is the default
// @param array If set, it will be filled with the parts of the composed url like parse_url() would return
function http_build_url($url, $parts=array(), $flags=HTTP_URL_REPLACE, &$new_url=false)
{
$keys = array('user', 'pass', 'port', 'path', 'query', 'fragment');
// HTTP_URL_STRIP_ALL becomes all the HTTP_URL_STRIP_Xs
if ($flags & HTTP_URL_STRIP_ALL) {
$flags |= HTTP_URL_STRIP_USER;
$flags |= HTTP_URL_STRIP_PASS;
$flags |= HTTP_URL_STRIP_PORT;
$flags |= HTTP_URL_STRIP_PATH;
$flags |= HTTP_URL_STRIP_QUERY;
$flags |= HTTP_URL_STRIP_FRAGMENT;
}
// HTTP_URL_STRIP_AUTH becomes HTTP_URL_STRIP_USER and HTTP_URL_STRIP_PASS
else if ($flags & HTTP_URL_STRIP_AUTH) {
$flags |= HTTP_URL_STRIP_USER;
$flags |= HTTP_URL_STRIP_PASS;
}
// Parse the original URL
$parse_url = parse_url($url);
// Scheme and Host are always replaced
if (isset($parts['scheme']))
$parse_url['scheme'] = $parts['scheme'];
if (isset($parts['host']))
$parse_url['host'] = $parts['host'];
// (If applicable) Replace the original URL with it's new parts
if ($flags & HTTP_URL_REPLACE) {
foreach ($keys as $key) {
if (isset($parts[$key]))
$parse_url[$key] = $parts[$key];
}
}
else {
// Join the original URL path with the new path
if (isset($parts['path']) && ($flags & HTTP_URL_JOIN_PATH)) {
if (isset($parse_url['path']))
$parse_url['path'] = rtrim(str_replace(basename($parse_url['path']), '', $parse_url['path']), '/') . '/' . ltrim($parts['path'], '/');
else
$parse_url['path'] = $parts['path'];
}
// Join the original query string with the new query string
if (isset($parts['query']) && ($flags & HTTP_URL_JOIN_QUERY)) {
if (isset($parse_url['query']))
$parse_url['query'] .= '&' . $parts['query'];
else
$parse_url['query'] = $parts['query'];
}
}
// Strips all the applicable sections of the URL
// Note: Scheme and Host are never stripped
foreach ($keys as $key) {
if ($flags & (int)constant('HTTP_URL_STRIP_' . strtoupper($key)))
unset($parse_url[$key]);
}
$new_url = $parse_url;
return
((isset($parse_url['scheme'])) ? $parse_url['scheme'] . '://' : '')
.((isset($parse_url['user'])) ? $parse_url['user'] . ((isset($parse_url['pass'])) ? ':' . $parse_url['pass'] : '') .'@' : '')
.((isset($parse_url['host'])) ? $parse_url['host'] : '')
.((isset($parse_url['port'])) ? ':' . $parse_url['port'] : '')
.((isset($parse_url['path'])) ? $parse_url['path'] : '')
.((isset($parse_url['query'])) ? '?' . $parse_url['query'] : '')
.((isset($parse_url['fragment'])) ? '#' . $parse_url['fragment'] : '')
;
}
}
/**
* Looks in an url for a query parameter and replaces it or creates if it does not exist
*
* @access public
* @param mixed $key
* @param mixed $value
* @param mixed $url
* @return void
*/
function push_param($key, $value, $url)
{
// Parse url
$url = parse_url($url);
// Prepopulate query string
$url_params = array();
if (!empty($url['query'])) {
parse_str($url['query'], $url_params);
}
// Push/change value
$url_params[$key] = $value;
// Build query string and replace current
$url['query'] = http_build_query($url_params);
// Output changed url
return http_build_url('', $url);
}
function remove_param($key, $url)
{
// Parse url
$url = parse_url($url);
// Prepopulate query string
$url_params = array();
if (!empty($url['query'])) {
parse_str($url['query'], $url_params);
}
// Remove parameter
unset($url_params[$key]);
// Build query string and replace current
$url['query'] = http_build_query($url_params);
// If no url parameters, unset query
if (empty($url_params))
unset($url['query']);
// Output changed url
return http_build_url('', $url);
}
<?php
$pagination_config = array();
$pagination_config['total_rows'] = 100; // Total number of rows
$pagination_config['per_page'] = 10; // Rows per page
$pagination_config['page'] = 2; // Current page
$pagination = new Pagination();
$pagination->initialize($pagination_config);
echo $pagination->create_links(); // Show pagination
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment