HTTP_Session
[ class tree: HTTP_Session ] [ index: HTTP_Session ] [ all elements ]

Source for file DB.php

Documentation is available at DB.php

  1. <?php
  2. //
  3. // +-----------------------------------------------------------------------+
  4. // | Copyright (c) 2002, Alexander Radivanovich                            |
  5. // | All rights reserved.                                                  |
  6. // |                                                                       |
  7. // | Redistribution and use in source and binary forms, with or without    |
  8. // | modification, are permitted provided that the following conditions    |
  9. // | are met:                                                              |
  10. // |                                                                       |
  11. // | o Redistributions of source code must retain the above copyright      |
  12. // |   notice, this list of conditions and the following disclaimer.       |
  13. // | o Redistributions in binary form must reproduce the above copyright   |
  14. // |   notice, this list of conditions and the following disclaimer in the |
  15. // |   documentation and/or other materials provided with the distribution.|
  16. // | o The names of the authors may not be used to endorse or promote      |
  17. // |   products derived from this software without specific prior written  |
  18. // |   permission.                                                         |
  19. // |                                                                       |
  20. // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   |
  21. // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     |
  22. // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
  23. // | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  |
  24. // | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
  25. // | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      |
  26. // | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
  27. // | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
  28. // | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   |
  29. // | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
  30. // | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  |
  31. // |                                                                       |
  32. // +-----------------------------------------------------------------------+
  33. // | Author: Alexander Radivanovich <info@wwwlab.net>                      |
  34. // +-----------------------------------------------------------------------+
  35. //
  36.  
  37. require_once 'HTTP/Session2/Container.php';
  38. require_once 'DB.php';
  39. require_once 'PEAR/Exception.php';
  40.  
  41. /**
  42.  * Database container for session data
  43.  *
  44.  * Create the following table to store session data
  45.  * <code>
  46.  * CREATE TABLE `sessiondata` (
  47.  *     `id` CHAR(32) NOT NULL,
  48.  *     `expiry` INT UNSIGNED NOT NULL DEFAULT 0,
  49.  *     `data` TEXT NOT NULL,
  50.  *     PRIMARY KEY (`id`)
  51.  * );
  52.  * </code>
  53.  *
  54.  * @author  Alexander Radivanovich <info@wwwlab.net>
  55.  * @package HTTP_Session
  56.  * @access  public
  57.  */
  58. {
  59.  
  60.     /**
  61.      * DB connection object
  62.      *
  63.      * @var object DB 
  64.      * @access private
  65.      */
  66.     private $db = null;
  67.  
  68.     /**
  69.      * Session data cache id
  70.      *
  71.      * @var mixed 
  72.      * @access private
  73.      */
  74.     private $crc = false;
  75.  
  76.     /**
  77.      * Constrtuctor method
  78.      *
  79.      * $options is an array with the options.<br>
  80.      * The options are:
  81.      * <ul>
  82.      * <li>'dsn' - The DSN string</li>
  83.      * <li>'table' - Table with session data, default is 'sessiondata'</li>
  84.      * <li>'autooptimize' - Boolean, 'true' to optimize
  85.      * the table on garbage collection, default is 'false'.</li>
  86.      * </ul>
  87.      *
  88.      * @access public
  89.      * @param  array  $options The options
  90.      * @return void 
  91.      */
  92.     public function __construct($options)
  93.     {
  94.         parent::__construct();
  95.         
  96.     $this->options['table'$options['table'];
  97.     $this->options['dsn']   sprintf(
  98.             '%s://%s:%s@%s/%s',
  99.             $options['dsn']['phptype'],
  100.             $options['dsn']['username'],
  101.             $options['dsn']['password'],
  102.             $options['dsn']['hostspec'],
  103.             $options['dsn']['database']
  104.         );
  105.     }
  106.  
  107.     /**
  108.      * Connect to database by using the given DSN string
  109.      *
  110.      * @access private
  111.      * @param  string DSN string
  112.      * @return mixed  Object on error, otherwise bool
  113.      */
  114.     private function connect($dsn)
  115.     {
  116.         if (is_string($dsn)) {
  117.             $this->db = DB::connect($dsn);
  118.         else if (is_object($dsn&& is_a($dsn'db_common')) {
  119.             $this->db $dsn;
  120.         else if (is_object($dsn&& DB::isError($dsn)) {
  121.             return new DB_Error($dsn->codePEAR_ERROR_DIE);
  122.         else {
  123.             return new PEAR_Error(
  124.                 "The given dsn was not valid in file " . __FILE__ . " at line " . __LINE__,
  125.                 41,
  126.                 PEAR_ERROR_RETURN,
  127.                 null,
  128.                 null
  129.             );
  130.         }
  131.         if (DB::isError($this->db)) {
  132.             return new DB_Error($this->db->codePEAR_ERROR_DIE);
  133.         }
  134.         return true;
  135.     }
  136.  
  137.     /**
  138.      * Set some default options
  139.      *
  140.      * @access private
  141.      */
  142.     private function setDefaults()
  143.     {
  144.         $this->options['dsn']          = null;
  145.         $this->options['table']        'sessiondata';
  146.         $this->options['autooptimize'= false;
  147.     }
  148.  
  149.     /**
  150.      * Establish connection to a database
  151.      *
  152.      */
  153.     public function open($save_path$session_name)
  154.     {
  155.         if (DB::isError($this->connect($this->options['dsn']))) {
  156.             return false;
  157.         else {
  158.             return true;
  159.         }
  160.     }
  161.  
  162.     /**
  163.      * Free resources
  164.      *
  165.      */
  166.     public function close()
  167.     {
  168.         return true;
  169.     }
  170.  
  171.     /**
  172.      * Read session data
  173.      *
  174.      */
  175.     public function read($id)
  176.     {
  177.         $query sprintf("SELECT data FROM %s WHERE id = %s AND expiry >= %d",$this->options['table'],$this->db->quote(md5($id)),time());
  178.         $result $this->db->getOne($query);
  179.         if (DB::isError($result)) {
  180.             new DB_Error($result->codePEAR_ERROR_DIE);
  181.             return false;
  182.         }
  183.         $this->crc strlen($resultcrc32($result);
  184.         return $result;
  185.     }
  186.  
  187.     /**
  188.      * Write session data
  189.      *
  190.      */
  191.     public function write($id$data)
  192.     {
  193.         if ((false !== $this->crc&& ($this->crc === strlen($datacrc32($data))) {
  194.             // $_SESSION hasn't been touched, no need to update the blob column
  195.             $query sprintf("UPDATE %s SET expiry = %d WHERE id = %s AND expiry >= %d",
  196.                              $this->options['table'],
  197.                              time(ini_get('session.gc_maxlifetime'),
  198.                              $this->db->quote(md5($id)),
  199.                              time()
  200.                              );
  201.         else {
  202.             // Check if table row already exists
  203.             $query sprintf("SELECT COUNT(id) FROM %s WHERE id = '%s'",
  204.                              $this->options['table'],
  205.                              md5($id)
  206.                              );
  207.             $result $this->db->getOne($query);
  208.             if (DB::isError($result)) {
  209.                 new DB_Error($result->codePEAR_ERROR_DIE);
  210.                 return false;
  211.             }
  212.             if (0 == intval($result)) {
  213.                 // Insert new row into table
  214.                 $query sprintf("INSERT INTO %s (id, expiry, data) VALUES (%s, %d, %s)",
  215.                                  $this->options['table'],
  216.                                  $this->db->quote(md5($id)),
  217.                                  time(ini_get('session.gc_maxlifetime'),
  218.                                  $this->db->quote($data)
  219.                                  );
  220.             else {
  221.                 // Update existing row
  222.                 $query sprintf("UPDATE %s SET expiry = %d, data = %s WHERE id = %s AND expiry >= %d",
  223.                                  $this->options['table'],
  224.                                  time(ini_get('session.gc_maxlifetime'),
  225.                                  $this->db->quote($data),
  226.                                  $this->db->quote(md5($id)),
  227.                                  time()
  228.                                  );
  229.             }
  230.         }
  231.         $result $this->db->query($query);
  232.         if (DB::isError($result)) {
  233.             new DB_Error($result->codePEAR_ERROR_DIE);
  234.             return false;
  235.         }
  236.  
  237.         return true;
  238.     }
  239.  
  240.     /**
  241.      * Destroy session data
  242.      *
  243.      */
  244.     public function destroy($id)
  245.     {
  246.         $query sprintf("DELETE FROM %s WHERE id = %s",
  247.                          $this->options['table'],
  248.                          $this->db->quote(md5($id))
  249.                          );
  250.         $result $this->db->query($query);
  251.         if (DB::isError($result)) {
  252.             new DB_Error($result->codePEAR_ERROR_DIE);
  253.             return false;
  254.         }
  255.  
  256.         return true;
  257.     }
  258.  
  259.     /**
  260.      * Garbage collection
  261.      *
  262.      */
  263.     public function gc($maxlifetime)
  264.     {
  265.         $query sprintf("DELETE FROM %s WHERE expiry < %d",
  266.                          $this->options['table'],
  267.                          time()
  268.                          );
  269.         $result $this->db->query($query);
  270.         if (DB::isError($result)) {
  271.             new DB_Error($result->codePEAR_ERROR_DIE);
  272.             return false;
  273.         }
  274.         if ($this->options['autooptimize']{
  275.             switch($this->db->type{
  276.                 case 'mysql':
  277.                     $query sprintf("OPTIMIZE TABLE %s"$this->options['table']);
  278.                     break;
  279.                 case 'pgsql':
  280.                     $query sprintf("VACUUM %s"$this->options['table']);
  281.                     break;
  282.                 default:
  283.                     $query = null;
  284.                     break;
  285.             }
  286.             if (isset($query)) {
  287.                 $result $this->db->query($query);
  288.                 if (DB::isError($result)) {
  289.                     new DB_Error($result->codePEAR_ERROR_DIE);
  290.                     return false;
  291.                 }
  292.             }
  293.         }
  294.  
  295.         return true;
  296.     }
  297. }

Documentation generated on Mon, 11 Mar 2019 15:11:36 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.