#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    5
    Rep Power
    0

    Pagination class


    Hi everyone,

    I'm currently writing a class that does pagination for arrays and database records. When the links are generated (1, 2, 3, next, etc) I've decided that the class should be able to retain any existing query string data in $_GET in addition to calculating the right index into the result set.

    My question is this: What approach would you suggest to create a new string that contains all the existing query data passed into the page? Would you use something like:

    Code:
    foreach ($_GET as $k => $v)
     ...
    (this did not seem to work for some reason)

    or simply split the $_SERVER['QUERY_STRING'] variable on the '&' character?

    My class will be doing this and then appending some internal query variable onto the end of it with calculated numbers. Something like:

    Code:
    ...other query variables...&my_class_var=calculated_value
    I would then create a link that sets the href to this string value.

    I'm looking for a robust solution so as not to lose any data so what approach would you guys recommend?
  2. #2
  3. Come play with me!
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    13,749
    Rep Power
    9397
    PHP Code:
    $get $_GET// make a copy
    /* do whatever you want to the copy: remove values, set values, etc */
    $url "/path/to/page?" http_build_query($get); 
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    5
    Rep Power
    0

    Thanks


    Thanks for the suggestion. I did go that route. The class now does retain the query data from page to page when navigating through the links. I don't really know what else to do to improve it so this was my finished code. As far as the db querying goes, it was written to use PHP MySQLi but it could probably be generalized for any db.

    Code:
    <?php
    
    # Author: XXX
    # Last Modified: 10/29/2013
    #
    # Class PaginatedResults
    # DESCRIPTION:
    #   This class represents a set of paginated results returned
    #   from a database.
    #
    # ASSUMPTIONS:
    #   The class by default assumes that there is a query string variable 's'
    #   (from $_GET) indicating the starting value of where to begin returning
    #   results.  A starting value is provided (0) if this is not set initially
    #   but on subsequent pages (links) it will have a proper value set by the class.
    #   This query variable name defaults to 's' but you can change it with the
    #   constructor to a different name if that one is already in use.
    #
    # DIRECTIONS FOR USE:
    #   Make an instance with the constructor by supplying the target page
    #   that will be pulling from the database, the number of items that page
    #   will be displaying, and the total number of records.  There are only
    #   two methods exposed -- get_results() and make_links().  Call get_results()
    #   to return the records to your calling code and make_links() to generate
    #   the links however many there are.
    #
    #   The get_results() method expects a query with a LIMIT clause such as
    #
    #   ... rest of query ... LIMIT <s>,<e>
    #
    #   where <s> and <e> respectively will correspond to the starting and
    #   ending values filled in by the class, you do not need to bother with
    #   knowing anything about the indices.  Just type "<s>,<e>" verbatim in
    #   your query for the LIMIT clause.  String replacement functions will
    #   plug in the right values.
    #
    # EXAMPLE USAGE:
    #   ...
    #   database connection code
    #   ...
    #   require_once('PaginatedResults.php');
    #   $pagination = new PaginatedResults($_SERVER['SCRIPT_NAME'], 10, 50, $connection);
    #   $results = $pagination->get_results("SELECT criteria FROM table_name LIMIT <s>,<e>");
    #
    #   while (($row = $results->fetch_row()) != NULL)
    #      ... do something with records ...
    #
    #   $pagination->make_links()
    #
    #   close database connection
    
    class PaginatedResults
    {
       protected $num_results;      # Total number of records
       protected $display_count;    # How many items each page will show
       protected $target_page;      # The page interacting with the database
       protected $start;            # Where to begin pulling records
       protected $number_of_pages;  # How many links need to be made
       protected $qv;               # Query string variable holding our calculated
                                    # starting value when a link is clicked
    
       function __construct($target, $display, $record_count, $conn, $qv = 's')
       {
          $this->target_page = $target;
          $this->display_count = ($display <= 0) ? 1 : $display;
          $this->num_results = $record_count;
          $this->db_conn = $conn;
          $this->qv = $qv;
          if (isset($_GET[$qv]) && is_numeric($_GET[$qv]))
             $this->start = intval($_GET[$qv]);
          else
             $this->start = 0;
          $this->number_of_pages = ceil($this->num_results / $this->display_count);
       }
    
       protected function get_current_page()
       { return intval(floor(($this->start / $this->display_count) + 1)); }
    
       public function get_results($query)
       {
          if (empty($query)) return -1;
    
          return $this->get_nth_result_set($query);
       }
    
       private function get_nth_result_set($query)
       {
          $newq = str_replace("<s>", "$this->start", $query);
          $newq = str_replace("<e>", "$this->display_count", $newq);
    
          $set = @$this->db_conn->query($newq);
    
          if ($set === FALSE) return NULL;
          else
             return $set;
       }
    
       public function make_links($current_css_class = NULL)
       {
          $curp = $this->get_current_page();
    
          $Gdata = (count($_GET) > 0) ? $_GET : array();
          
          if ($curp > 1)
           {
             $Gdata[$this->qv] = ($this->start - $this->display_count);
             echo "<a href='$this->target_page?" . http_build_query($Gdata) . "'>Previous</a>";
           }
          for ($i = 1; $i <= $this->number_of_pages; $i++)
           {
             if ($i != $curp)
              {
                if ($i == 1)
                 {
                   $Gdata[$this->qv] = 0;
                   echo "<a href='$this->target_page?" . http_build_query($Gdata) . "'>$i</a>";
                 }
                else
                 {
                   $Gdata[$this->qv] = (($i - 1) * $this->display_count);
                   echo "<a href='$this->target_page?" . http_build_query($Gdata) . "'>$i</a>";
                 }
              }
             else
                echo ($current_css_class) ? "<span class=\"$current_css_class\">$i</span>" : "$i";
           }
          if ($curp < $this->number_of_pages)
           {
             $Gdata[$this->qv] = ($this->start + $this->display_count);
             echo "<a href='$this->target_page?" . http_build_query($Gdata) . "'>Next</a>";
           }
       }
    }
    
    # Class PaginatedArrayResults
    # DESCRIPTION:
    #   This class represents a set of paginated results
    #   returned from an array.
    #
    # ASSUMPTIONS:
    #   Same for PaginatedResults.
    #
    # DIRECTIONS FOR USE:
    #   Make an instance with the constructor and supply
    #   the target page, the number of items to show, and
    #   the array of values.  As with the PaginatedResults class
    #   you can optionally change the query string variable to use.
    #   The get_results() method is the only overriden method but
    #   make_links() is inherited from the parent class so the two
    #   methods available publicly are the same two for its parent.
    #
    #   Because an array is expected, there is no need to pass in a 
    #   database query to get_results() -- just call it directly,
    #   specifying the type of sort order you want: by key or by value.
    #
    # EXAMPLE USAGE:
    #   ...
    #   get an array somehow, either from database records
    #   or one coded literally in your script.
    #   ...
    #   require_once('PaginatedResults.php');
    #   $pagination = new PaginatedArrayResults($_SERVER['SCRIPT_NAME'], 10, $array);
    #   $results = $pagination->get_results();
    #
    #   foreach ($results as $element)
    #      ... do something with elements ...
    #
    #   $pagination->make_links()
    #
    define('PAGE_BY_KEY', 1);
    define('PAGE_BY_VALUE', 2);
    
    class PaginatedArrayResults extends PaginatedResults
    {
       private $paged_array;
    
       function __construct($target, $display, $avalues, $qv = 's')
       {
          $this->target_page = $target;
          $this->display_count = ($display <= 0) ? 1 : $display;
          if (!is_array($avalues))
             throw new Exception("PaginatedResults.php: PaginatedArrayResults::__construct(): "
                                   . "Parameter (3) is not an array.");
          else
             $this->paged_array = $avalues;
          $this->num_results = count($avalues);
          $this->qv = $qv;
          if (isset($_GET[$qv]) && is_numeric($_GET[$qv]))
             $this->start = intval($_GET[$qv]);
          else
             $this->start = 0;
          $this->number_of_pages = ceil($this->num_results / $this->display_count);
       }
    
       public function get_results($order_type = PAGE_BY_KEY)
       {
          switch ($order_type)
           {
             case PAGE_BY_KEY:
                ksort($this->paged_array);
                break;
    
             case PAGE_BY_VALUE:
                asort($this->paged_array);
                break;
    
             default: break;
           }
          return array_slice($this->paged_array, $this->start, $this->display_count, TRUE);
       }
    }
    
    ?>

IMN logo majestic logo threadwatch logo seochat tools logo