Advertisement
Guest User

Untitled

a guest
Sep 18th, 2018
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 7.69 KB | None | 0 0
  1. <?php
  2.  
  3.     class db{
  4.        
  5.         static $host;
  6.         static $user;
  7.         static $pass;
  8.         static $db;
  9.        
  10.         static $charset = 'UTF8';
  11.        
  12.         static $pdo;
  13.        
  14.         /**
  15.          * Creates a PDO database object. If not arguments are passed and a connection has already been
  16.          * established the function will do nothing.
  17.          * @param string $host optional MySQL server address
  18.          * @param string $user optional MySQL username
  19.          * @param string $pass optional MySQL password
  20.          * @param string $pass optional MySQL database name
  21.          */
  22.         static function connect($host = null, $user = null, $pass = null, $db = null){
  23.            
  24.             if($host !== null) self::$host = $host;
  25.             if($user !== null) self::$user = $user;
  26.             if($pass !== null) self::$pass = $pass;
  27.             if($db !== null) self::$db = $db;
  28.            
  29.             $pdo = &self::$pdo;
  30.             if($pdo && $host === null) return;
  31.            
  32.             $dsn = sprintf('mysql:host=%s;dbname=%s;charset=%s', self::$host, self::$db, self::$charset);
  33.            
  34.             $options = array(
  35.                 PDO::MYSQL_ATTR_INIT_COMMAND => sprintf('SET NAMES %s', self::$charset)
  36.             );
  37.            
  38.             $pdo = new PDO($dsn, self::$user, self::$pass, $options);
  39.             $pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
  40.             $pdo->setAttribute( PDO::ATTR_EMULATE_PREPARES, false );
  41.            
  42.         }
  43.        
  44.         /**
  45.          * Runs a prepared query with parameters. Parameter keys in the query must be prefixed
  46.          * with : (e.g 'SELECT * FROM `table` WHERE `name` = :name')
  47.          * @param string $query MySQL query
  48.          * @param array $params optional Key/value array
  49.          * @return object
  50.          */
  51.         static function query($query, $params = null){
  52.            
  53.             # Add SQL_CALC_FOUND_ROWS is missing from a SELECT query
  54.             if(!preg_match('/^\s+SELECT\s+SQL_CALC_FOUND_ROWS/i', $query)){
  55.                 $query = preg_replace('/^((\s+)?SELECT)(\s+)/i', '${1} SQL_CALC_FOUND_ROWS ${2}', $query);
  56.             }
  57.            
  58.             $found_rows = 0;
  59.             $affected_rows = 0;
  60.             $num_rows = 0;
  61.             $rows = array();
  62.             $error = null;
  63.             $params = (array)$params;
  64.             $last_insert_id = null;
  65.            
  66.             try{
  67.                 $pdo = &self::$pdo;
  68.                 self::connect();
  69.                
  70.                 # Get rows
  71.                 $stmt = $pdo->prepare($query);
  72.                
  73.                 # Bind name/key params
  74.                 foreach($params as $key => $value){
  75.                     if($key[0] != ':') $key = ':' . $key;
  76.                    
  77.                     switch(gettype($value)){
  78.                         case 'integer':
  79.                             $type = PDO::PARAM_INT;
  80.                             break;
  81.                         default:
  82.                             $type = PDO::PARAM_STR;
  83.                     }
  84.                    
  85.                     $stmt->bindValue($key, $value, $type);
  86.                 }
  87.                
  88.                 $stmt->execute();
  89.                 $rows = $stmt->fetchAll(PDO::FETCH_OBJ);
  90.                 $last_insert_id = $pdo->lastInsertId();
  91.                
  92.                 $affected_rows = $stmt->rowCount();
  93.                
  94.                 # Count found rows
  95.                 $stmt = $pdo->prepare("SELECT FOUND_ROWS()");
  96.                 $stmt->execute();
  97.                 $found_rows = (int)$stmt->fetchColumn(0);
  98.                
  99.             }
  100.             catch(Exception $e){
  101.                 $error = $e->getMessage();
  102.             }
  103.            
  104.             return (object)array(
  105.                 'found_rows' => $found_rows,
  106.                 'affected_rows' => $affected_rows,
  107.                 'last_insert_id' => $last_insert_id,
  108.                 'rows' => $rows,
  109.                 'error' => $error,
  110.                 'params' => $params,
  111.                 'query' => $query
  112.             );
  113.            
  114.         }
  115.        
  116.     }
  117.    
  118.     class db_select_paginator{
  119.        
  120.         public $classes = array('paginator');
  121.         public $uri_pattern; // optional, e.g '/something/%s', '/results?page=%s'
  122.        
  123.         public $text_first = 'First';
  124.         public $text_prev = 'Prev';
  125.         public $text_next = 'Next';
  126.         public $text_last = 'Last';
  127.        
  128.         public $wrapper_tag = 'ul';
  129.         public $item_tag = 'li';
  130.        
  131.         private $result;
  132.         private $margin = 3; // Page numbers to be shown either side of the current page
  133.        
  134.         /**
  135.          * @param object $result Object returned from db::query() for a SELECT query
  136.          * @return object
  137.          */
  138.         public function __construct($result){
  139.             $this->result = $result;
  140.         }
  141.        
  142.         /**
  143.          * @return string URI pattern
  144.          */
  145.         private function default_uri_pattern(){
  146.             $uri = preg_replace('/\?.+$/', '', $_SERVER['REQUEST_URI']);
  147.             $qs = $_GET;
  148.             unset($qs['page']);
  149.             $qs = http_build_query($qs);
  150.             $qs .= ($qs ? '&' : '') . 'page=%s';
  151.             return sprintf('%s?%s', $uri, $qs);
  152.         }
  153.        
  154.         /**
  155.          * @param int $page Page number
  156.          * @return string URI
  157.          */
  158.         public function uri($page){
  159.             $pattern = (isset($this->uri_pattern) ? $this->uri_pattern : $this->default_uri_pattern());
  160.             return sprintf($pattern, $page);
  161.         }
  162.        
  163.         /**
  164.          * @param int $page Page number
  165.          * @param string $text optional Link text
  166.          * @param string HTML
  167.          */
  168.         private function render_page_link($page, $text = null){
  169.            
  170.             $current_page = $this->current_page();
  171.            
  172.             $classes = array();
  173.             if($text === null) $classes[] = sprintf('paginator-page-%s', $page);
  174.             if($text !== null) $classes[] = sprintf('paginator-%s', preg_replace('/[^a-z0-9]{1,}/i', '-', strtolower($text)) );
  175.  
  176.             if($text === null){
  177.                 if($page == 1) $classes[] = 'paginator-numbered-first';
  178.                 if($page == $this->total_pages()) $classes[] = 'paginator-numbered-last';
  179.                 $text = $page;
  180.             }
  181.            
  182.             if($current_page == $page) $classes[] = 'paginator-active';
  183.            
  184.             $class = implode(' ', $classes);
  185.            
  186.             $uri = $this->uri($page);
  187.             return sprintf('<%s class="%s"><a href="%s">%s</a></%s>', $this->item_tag, $class, $uri, $text, $this->item_tag);
  188.            
  189.         }
  190.        
  191.         /**
  192.          * @return string HTML
  193.          */
  194.         private function render_page_filler(){
  195.             return '<li class="paginator-page-filler">...</li>';
  196.         }
  197.        
  198.         /**
  199.          * Uses the 'limit' parameter passed to a query and the number of rows found to calculate the
  200.          * total number of pages
  201.          * @return int
  202.          */
  203.         public function total_pages(){
  204.             return ceil($this->result->found_rows / $this->result->params['limit']);
  205.         }
  206.        
  207.         /**
  208.          * Derives the current page from the 'offset' and 'limit' parameters that were used in the SELECT query
  209.          * @return int
  210.          */
  211.         public function current_page(){
  212.             return (int)($this->result->params['offset'] / $this->result->params['limit']) + 1;
  213.         }
  214.        
  215.         /**
  216.          * @return string HTML
  217.          */
  218.         public function render(){
  219.            
  220.             $total_pages = $this->total_pages();
  221.             $current_page = $this->current_page();
  222.            
  223.             $start_page = $current_page - $this->margin;
  224.             if($start_page < 1) $start_page = 1;
  225.            
  226.             $end_page = $current_page + $this->margin;
  227.             if($end_page > $total_pages) $end_page = $total_pages;
  228.            
  229.             $class = implode(' ', $this->classes);
  230.            
  231.             $output = sprintf('<%s class="%s">', $this->wrapper_tag, $class);
  232.                 $output .= $this->render_page_link(1, $this->text_first);
  233.                 if($current_page > 1) $output .= $this->render_page_link($current_page - 1, $this->text_prev);
  234.                 if($start_page > 1) $output .= $this->render_page_filler();
  235.                 for($i = $start_page; $i <= $end_page; $i++){
  236.                     $output .= $this->render_page_link($i);
  237.                 }
  238.                 if($end_page < $total_pages) $output .= $this->render_page_filler();
  239.                 if($current_page < $total_pages) $output .= $this->render_page_link($current_page + 1, $this->text_next);
  240.                 $output .= $this->render_page_link($total_pages, $this->text_last);
  241.             $output .= sprintf('</%s>', $this->wrapper_tag);
  242.            
  243.             return $output;
  244.            
  245.         }
  246.        
  247.         /**
  248.          * Alias for the render() method
  249.          * @return string HTML
  250.          */
  251.         public function __toString(){
  252.             return $this->render();
  253.         }
  254.        
  255.     }
  256.    
  257.     // ----------------------------------------- Usage -----------------------------------------
  258.    
  259.     db::connect('localhost', 'dev', 'password', 'test_db');
  260.        
  261.     $current_page = (isset($_GET['page']) ? (int)$_GET['page'] : 1);
  262.     $per_page = 5;
  263.        
  264.     $params = array(
  265.         'offset' => $per_page * ($current_page - 1),
  266.         'limit' => $per_page
  267.     );
  268.     $result = db::query('SELECT * FROM `things` LIMIT :limit OFFSET :offset', $params);
  269.    
  270.     $paginator = new db_select_paginator($result);
  271.     echo $paginator;
  272.    
  273.     foreach($result->rows as $row){
  274.         echo sprintf('<p>#%s: %s</p>', $row->id, $row->name);
  275.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement