home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / HTTP / Session / Container / DB.php next >
Encoding:
PHP Script  |  2008-07-02  |  11.2 KB  |  364 lines

  1. <?php
  2.  
  3. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  4.  
  5. /**
  6.  * Database container for session data
  7.  *
  8.  * PEAR::DB database container
  9.  *
  10.  * PHP version 4
  11.  *
  12.  * LICENSE: This source file is subject to version 3.0 of the PHP license
  13.  * that is available through the world-wide-web at the following URI:
  14.  * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
  15.  * the PHP License and are unable to obtain it through the web, please
  16.  * send a note to license@php.net so we can mail you a copy immediately.
  17.  *
  18.  * @category  HTTP
  19.  * @package   HTTP_Session
  20.  * @author    Alexander Radivanovich <info@wwwlab.net>
  21.  * @author    David Costa <gurugeek@php.net>
  22.  * @author    Michael Metz <pear.metz@speedpartner.de>
  23.  * @author    Stefan Neufeind <pear.neufeind@speedpartner.de>
  24.  * @author    Torsten Roehr <torsten.roehr@gmx.de>
  25.  * @copyright 1997-2005 The PHP Group
  26.  * @license   http://www.php.net/license/3_0.txt  PHP License 3.0
  27.  * @version   CVS: $Id: DB.php,v 1.7 2007/07/14 12:11:54 troehr Exp $
  28.  * @link      http://pear.php.net/package/HTTP_Session
  29.  * @since     File available since Release 0.4.0
  30.  */
  31.  
  32. require_once 'HTTP/Session/Container.php';
  33. require_once 'DB.php';
  34.  
  35. /**
  36.  * Database container for session data
  37.  *
  38.  * Create the following table to store session data
  39.  * <code>
  40.  * CREATE TABLE `sessiondata` (
  41.  *     `id` CHAR(32) NOT NULL,
  42.  *     `expiry` INT UNSIGNED NOT NULL DEFAULT 0,
  43.  *     `data` TEXT NOT NULL,
  44.  *     PRIMARY KEY (`id`)
  45.  * );
  46.  * </code>
  47.  *
  48.  * @category  HTTP
  49.  * @package   HTTP_Session
  50.  * @author    David Costa <gurugeek@php.net>
  51.  * @author    Michael Metz <pear.metz@speedpartner.de>
  52.  * @author    Stefan Neufeind <pear.neufeind@speedpartner.de>
  53.  * @author    Torsten Roehr <torsten.roehr@gmx.de>
  54.  * @copyright 1997-2005 The PHP Group
  55.  * @license   http://www.php.net/license/3_0.txt  PHP License 3.0
  56.  * @version   Release: @package_version@
  57.  * @link      http://pear.php.net/package/HTTP_Session
  58.  * @since     Class available since Release 0.4.0
  59.  */
  60. class HTTP_Session_Container_DB extends HTTP_Session_Container
  61. {
  62.     /**
  63.      * DB connection object
  64.      *
  65.      * @var object DB
  66.      * @access private
  67.      */
  68.     var $db = null;
  69.  
  70.     /**
  71.      * Session data cache id
  72.      *
  73.      * @var mixed
  74.      * @access private
  75.      */
  76.     var $crc = false;
  77.  
  78.     /**
  79.      * Constrtuctor method
  80.      *
  81.      * $options is an array with the options.<br>
  82.      * The options are:
  83.      * <ul>
  84.      * <li>'dsn' - The DSN string</li>
  85.      * <li>'table' - Table with session data, default is 'sessiondata'</li>
  86.      * <li>'autooptimize' - Boolean, 'true' to optimize
  87.      * the table on garbage collection, default is 'false'.</li>
  88.      * </ul>
  89.      *
  90.      * @param array $options Options
  91.      *
  92.      * @access public
  93.      * @return object
  94.      */
  95.     function HTTP_Session_Container_DB($options)
  96.     {
  97.         $this->_setDefaults();
  98.         if (is_array($options)) {
  99.             $this->_parseOptions($options);
  100.         } else {
  101.             $this->options['dsn'] = $options;
  102.         }
  103.     }
  104.  
  105.     /**
  106.      * Connect to database by using the given DSN string
  107.      *
  108.      * @param string $dsn DSN string
  109.      *
  110.      * @access private
  111.      * @return mixed   Object on error, otherwise bool
  112.      */
  113.     function _connect($dsn)
  114.     {
  115.         if (is_string($dsn) || is_array($dsn)) {
  116.             $this->db = DB::connect($dsn);
  117.         } else if (is_object($dsn) && is_a($dsn, "db_common")) {
  118.             $this->db = $dsn;
  119.         } else if (is_object($dsn) && DB::isError($dsn)) {
  120.             return new DB_Error($dsn->code, PEAR_ERROR_DIE);
  121.         } else {
  122.             return new PEAR_Error("The given dsn was not valid in file " . __FILE__
  123.                                   . " at line " . __LINE__,
  124.                                   41,
  125.                                   PEAR_ERROR_RETURN,
  126.                                   null,
  127.                                   null
  128.                                   );
  129.  
  130.         }
  131.  
  132.         if (DB::isError($this->db)) {
  133.             return new DB_Error($this->db->code, PEAR_ERROR_DIE);
  134.         }
  135.  
  136.         return true;
  137.     }
  138.  
  139.     /**
  140.      * Set some default options
  141.      *
  142.      * @access private
  143.      * @return void
  144.      */
  145.     function _setDefaults()
  146.     {
  147.         $this->options['dsn']          = null;
  148.         $this->options['table']        = 'sessiondata';
  149.         $this->options['autooptimize'] = false;
  150.     }
  151.  
  152.     /**
  153.      * Establish connection to a database
  154.      *
  155.      * @param string $save_path    Save path
  156.      * @param string $session_name Session name
  157.      *
  158.      * @return bool
  159.      */
  160.     function open($save_path, $session_name)
  161.     {
  162.         if (DB::isError($this->_connect($this->options['dsn']))) {
  163.             return false;
  164.         } else {
  165.             return true;
  166.         }
  167.     }
  168.  
  169.     /**
  170.      * Free resources
  171.      *
  172.      * @return void
  173.      */
  174.     function close()
  175.     {
  176.         return true;
  177.     }
  178.  
  179.     /**
  180.      * Read session data
  181.      *
  182.      * @param string $id Session id
  183.      *
  184.      * @return void
  185.      */
  186.     function read($id)
  187.     {
  188.         $query = sprintf("SELECT data FROM %s WHERE id = %s AND expiry >= %d",
  189.                          $this->options['table'],
  190.                          $this->db->quoteSmart(md5($id)),
  191.                          time());
  192.         $result = $this->db->getOne($query);
  193.         if (DB::isError($result)) {
  194.             new DB_Error($result->code, PEAR_ERROR_DIE);
  195.             return false;
  196.         }
  197.         $this->crc = strlen($result) . crc32($result);
  198.         return $result;
  199.     }
  200.  
  201.     /**
  202.      * Write session data
  203.      *
  204.      * @param string $id   Session id
  205.      * @param mixed  $data Data
  206.      *
  207.      * @return bool
  208.      */
  209.     function write($id, $data)
  210.     {
  211.         if ((false !== $this->crc) &&
  212.             ($this->crc === strlen($data) . crc32($data))) {
  213.             // $_SESSION hasn't been touched, no need to update the blob column
  214.             $query = sprintf("UPDATE %s SET expiry = %d WHERE id = %s",
  215.                              $this->options['table'],
  216.                              time() + ini_get('session.gc_maxlifetime'),
  217.                              $this->db->quoteSmart(md5($id)));
  218.         } else {
  219.             // Check if table row already exists
  220.             $query = sprintf("SELECT COUNT(id) FROM %s WHERE id = %s",
  221.                              $this->options['table'],
  222.                              $this->db->quoteSmart(md5($id)));
  223.             $result = $this->db->getOne($query);
  224.             if (DB::isError($result)) {
  225.                 new DB_Error($result->code, PEAR_ERROR_DIE);
  226.                 return false;
  227.             }
  228.             if (0 == intval($result)) {
  229.                 // Insert new row into table
  230.                 $query = sprintf("INSERT INTO %s (id, expiry, data) VALUES (%s, %d, %s)",
  231.                                  $this->options['table'],
  232.                                  $this->db->quoteSmart(md5($id)),
  233.                                  time() + ini_get('session.gc_maxlifetime'),
  234.                                  $this->db->quoteSmart($data));
  235.             } else {
  236.                 // Update existing row
  237.                 $query = sprintf("UPDATE %s SET expiry = %d, data = %s WHERE id = %s",
  238.                                  $this->options['table'],
  239.                                  time() + ini_get('session.gc_maxlifetime'),
  240.                                  $this->db->quoteSmart($data),
  241.                                  $this->db->quoteSmart(md5($id)));
  242.             }
  243.         }
  244.         $result = $this->db->query($query);
  245.         if (DB::isError($result)) {
  246.             new DB_Error($result->code, PEAR_ERROR_DIE);
  247.             return false;
  248.         }
  249.  
  250.         return true;
  251.     }
  252.  
  253.     /**
  254.      * Destroy session data
  255.      *
  256.      * @param string $id Session id
  257.      *
  258.      * @return void
  259.      */
  260.     function destroy($id)
  261.     {
  262.         $query = sprintf("DELETE FROM %s WHERE id = %s",
  263.                          $this->options['table'],
  264.                          $this->db->quoteSmart(md5($id)));
  265.         $result = $this->db->query($query);
  266.         if (DB::isError($result)) {
  267.             new DB_Error($result->code, PEAR_ERROR_DIE);
  268.             return false;
  269.         }
  270.  
  271.         return true;
  272.     }
  273.  
  274.     /**
  275.      * Replicate session data to table specified in option 'replicateBeforeDestroy'
  276.      *
  277.      * @param string $targetTable Table to replicate to
  278.      * @param string $id          Id of record to replicate
  279.      *
  280.      * @access private
  281.      * @return bool
  282.      */
  283.     function replicate($targetTable, $id = null)
  284.     {
  285.         if (is_null($id)) {
  286.             $id = HTTP_Session::id();
  287.         }
  288.  
  289.         // Check if table row already exists
  290.         $query = sprintf("SELECT COUNT(id) FROM %s WHERE id = %s",
  291.                          $targetTable,
  292.                          $this->db->quoteSmart(md5($id)));
  293.         $result = $this->db->getOne($query);
  294.         if (DB::isError($result)) {
  295.             new DB_Error($result->code, PEAR_ERROR_DIE);
  296.             return false;
  297.         }
  298.  
  299.         // Insert new row into dest table
  300.         if (0 == intval($result)) {
  301.             $query = sprintf("INSERT INTO %s SELECT * FROM %s WHERE id = %s",
  302.                              $targetTable,
  303.                              $this->options['table'],
  304.                              $this->db->quoteSmart(md5($id)));
  305.  
  306.         } else {
  307.             // Update existing row
  308.             $query = sprintf("UPDATE %s dst, %s src SET dst.expiry = src.expiry, dst.data = src.data WHERE dst.id = src.id AND src.id = %s",
  309.                              $targetTable,
  310.                              $this->options['table'],
  311.                              $this->db->quoteSmart(md5($id)));
  312.         }
  313.  
  314.         $result = $this->db->query($query);
  315.         if (DB::isError($result)) {
  316.             new DB_Error($result->code, PEAR_ERROR_DIE);
  317.             return false;
  318.         }
  319.  
  320.         return true;
  321.     }
  322.  
  323.     /**
  324.      * Garbage collection
  325.      *
  326.      * @param int $maxlifetime Maximum lifetime
  327.      *
  328.      * @return bool
  329.      */
  330.     function gc($maxlifetime)
  331.     {
  332.         $query = sprintf("DELETE FROM %s WHERE expiry < %d",
  333.                          $this->options['table'],
  334.                          time());
  335.         $result = $this->db->query($query);
  336.         if (DB::isError($result)) {
  337.             new DB_Error($result->code, PEAR_ERROR_DIE);
  338.             return false;
  339.         }
  340.         if ($this->options['autooptimize']) {
  341.             switch($this->db->phptype) {
  342.             case 'mysql':
  343.                 $query = sprintf("OPTIMIZE TABLE %s", $this->options['table']);
  344.                 break;
  345.             case 'pgsql':
  346.                 $query = sprintf("VACUUM %s", $this->options['table']);
  347.                 break;
  348.             default:
  349.                 $query = null;
  350.                 break;
  351.             }
  352.             if (isset($query)) {
  353.                 $result = $this->db->query($query);
  354.                 if (DB::isError($result)) {
  355.                     new DB_Error($result->code, PEAR_ERROR_DIE);
  356.                     return false;
  357.                 }
  358.             }
  359.         }
  360.  
  361.         return true;
  362.     }
  363. }
  364. ?>