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 / MDB.php < prev    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::MDB 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: MDB.php,v 1.5 2007/07/14 12:11:55 troehr Exp $
  28.  * @link      http://pear.php.net/package/HTTP_Session
  29.  * @since     File available since Release 0.5.0
  30.  */
  31.  
  32. require_once 'HTTP/Session/Container.php';
  33. require_once 'MDB.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_MDB extends HTTP_Session_Container
  61. {
  62.  
  63.     /**
  64.      * MDB connection object
  65.      *
  66.      * @var object MDB
  67.      * @access private
  68.      */
  69.     var $db = null;
  70.  
  71.     /**
  72.      * Session data cache id
  73.      *
  74.      * @var mixed
  75.      * @access private
  76.      */
  77.     var $crc = false;
  78.  
  79.     /**
  80.      * Constructor method
  81.      *
  82.      * $options is an array with the options.<br>
  83.      * The options are:
  84.      * <ul>
  85.      * <li>'dsn' - The DSN string</li>
  86.      * <li>'table' - Table with session data, default is 'sessiondata'</li>
  87.      * <li>'autooptimize' - Boolean, 'true' to optimize
  88.      * the table on garbage collection, default is 'false'.</li>
  89.      * </ul>
  90.      *
  91.      * @param array $options Options
  92.      *
  93.      * @access public
  94.      * @return object
  95.      */
  96.     function HTTP_Session_Container_MDB($options)
  97.     {
  98.         $this->_setDefaults();
  99.         if (is_array($options)) {
  100.             $this->_parseOptions($options);
  101.         } else {
  102.             $this->options['dsn'] = $options;
  103.         }
  104.     }
  105.  
  106.     /**
  107.      * Connect to database by using the given DSN string
  108.      *
  109.      * @param string $dsn DSN string
  110.      *
  111.      * @access private
  112.      * @return mixed  Object on error, otherwise bool
  113.      */
  114.     function _connect($dsn)
  115.     {
  116.         if (is_string($dsn) || is_array($dsn)) {
  117.             $this->db = MDB::connect($dsn);
  118.         } else if (is_object($dsn) && is_a($dsn, 'mdb_common')) {
  119.             $this->db = $dsn;
  120.         } else if (is_object($dsn) && MDB::isError($dsn)) {
  121.             return new MDB_Error($dsn->code, PEAR_ERROR_DIE);
  122.         } else {
  123.             return new PEAR_Error("The given dsn was not valid in file " . __FILE__ 
  124.                                   . " at line " . __LINE__,
  125.                                   41,
  126.                                   PEAR_ERROR_RETURN,
  127.                                   null,
  128.                                   null
  129.                                   );
  130.  
  131.         }
  132.  
  133.         if (MDB::isError($this->db)) {
  134.             return new MDB_Error($this->db->code, PEAR_ERROR_DIE);
  135.         }
  136.  
  137.         return true;
  138.     }
  139.  
  140.     /**
  141.      * Set some default options
  142.      *
  143.      * @access private
  144.      * @return void
  145.      */
  146.     function _setDefaults()
  147.     {
  148.         $this->options['dsn']          = null;
  149.         $this->options['table']        = 'sessiondata';
  150.         $this->options['autooptimize'] = false;
  151.     }
  152.  
  153.     /**
  154.      * Establish connection to a database
  155.      *
  156.      * @param string $save_path    Save path
  157.      * @param string $session_name Session name
  158.      *
  159.      * @return bool
  160.      */
  161.     function open($save_path, $session_name)
  162.     {
  163.         if (MDB::isError($this->_connect($this->options['dsn']))) {
  164.             return false;
  165.         } else {
  166.             return true;
  167.         }
  168.     }
  169.  
  170.     /**
  171.      * Free resources
  172.      *
  173.      * @return bool
  174.      */
  175.     function close()
  176.     {
  177.         return true;
  178.     }
  179.  
  180.     /**
  181.      * Read session data
  182.      *
  183.      * @param string $id Session id
  184.      *
  185.      * @return mixed
  186.      */
  187.     function read($id)
  188.     {
  189.         $query = sprintf("SELECT data FROM %s WHERE id = %s AND expiry >= %d",
  190.                          $this->options['table'],
  191.                          $this->db->getTextValue(md5($id)),
  192.                          time());
  193.         $result = $this->db->getOne($query);
  194.         if (MDB::isError($result)) {
  195.             new MDB_Error($result->code, PEAR_ERROR_DIE);
  196.             return false;
  197.         }
  198.         $this->crc = strlen($result) . crc32($result);
  199.         return $result;
  200.     }
  201.  
  202.     /**
  203.      * Write session data
  204.      *
  205.      * @param string $id   Session id
  206.      * @param mixed  $data Data
  207.      *
  208.      * @return bool
  209.      */
  210.     function write($id, $data)
  211.     {
  212.         if ((false !== $this->crc) && 
  213.             ($this->crc === strlen($data) . crc32($data))) {
  214.             // $_SESSION hasn't been touched, no need to update the blob column
  215.             $query = sprintf("UPDATE %s SET expiry = %d WHERE id = %s",
  216.                              $this->options['table'],
  217.                              time() + ini_get('session.gc_maxlifetime'),
  218.                              $this->db->getTextValue(md5($id)));
  219.         } else {
  220.             // Check if table row already exists
  221.             $query = sprintf("SELECT COUNT(id) FROM %s WHERE id = %s",
  222.                              $this->options['table'],
  223.                              $this->db->getTextValue(md5($id)));
  224.             $result = $this->db->getOne($query);
  225.             if (MDB::isError($result)) {
  226.                 new MDB_Error($result->code, PEAR_ERROR_DIE);
  227.                 return false;
  228.             }
  229.             if (0 == intval($result)) {
  230.                 // Insert new row into table
  231.                 $query = sprintf("INSERT INTO %s (id, expiry, data) VALUES (%s, %d, %s)",
  232.                                  $this->options['table'],
  233.                                  $this->db->getTextValue(md5($id)),
  234.                                  time() + ini_get('session.gc_maxlifetime'),
  235.                                  $this->db->getTextValue($data));
  236.             } else {
  237.                 // Update existing row
  238.                 $query = sprintf("UPDATE %s SET expiry = %d, data = %s WHERE id = %s",
  239.                                  $this->options['table'],
  240.                                  time() + ini_get('session.gc_maxlifetime'),
  241.                                  $this->db->getTextValue($data),
  242.                                  $this->db->getTextValue(md5($id)));
  243.             }
  244.         }
  245.         $result = $this->db->query($query);
  246.         if (MDB::isError($result)) {
  247.             new MDB_Error($result->code, PEAR_ERROR_DIE);
  248.             return false;
  249.         }
  250.  
  251.         return true;
  252.     }
  253.  
  254.     /**
  255.      * Destroy session data
  256.      *
  257.      * @param string $id Session id
  258.      *
  259.      * @return bool
  260.      */
  261.     function destroy($id)
  262.     {
  263.         $query = sprintf("DELETE FROM %s WHERE id = %s",
  264.                          $this->options['table'],
  265.                          $this->db->getTextValue(md5($id)));
  266.         $result = $this->db->query($query);
  267.         if (MDB::isError($result)) {
  268.             new MDB_Error($result->code, PEAR_ERROR_DIE);
  269.             return false;
  270.         }
  271.  
  272.         return true;
  273.     }
  274.  
  275.     /**
  276.      * Replicate session data to table specified in option 'replicateBeforeDestroy'
  277.      *
  278.      * @param string $targetTable Table to replicate to
  279.      * @param string $id          Id of record to replicate
  280.      *
  281.      * @access private
  282.      * @return bool
  283.      */
  284.     function replicate($targetTable, $id = null)
  285.     {
  286.         if (is_null($id)) {
  287.             $id = HTTP_Session::id();
  288.         }
  289.  
  290.         // Check if table row already exists
  291.         $query = sprintf("SELECT COUNT(id) FROM %s WHERE id = %s",
  292.                          $targetTable,
  293.                          $this->db->getTextValue(md5($id)));
  294.         $result = $this->db->getOne($query);
  295.         if (MDB::isError($result)) {
  296.             new MDB_Error($result->code, PEAR_ERROR_DIE);
  297.             return false;
  298.         }
  299.  
  300.         // Insert new row into dest table
  301.         if (0 == intval($result)) {
  302.             $query = sprintf("INSERT INTO %s SELECT * FROM %s WHERE id = %s",
  303.                              $targetTable,
  304.                              $this->options['table'],
  305.                              $this->db->getTextValue(md5($id)));
  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->getTextValue(md5($id)));
  312.         }
  313.  
  314.         $result = $this->db->query($query);
  315.         if (MDB::isError($result)) {
  316.             new MDB_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 (MDB::isError($result)) {
  337.             new MDB_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 (MDB::isError($result)) {
  355.                     new MDB_Error($result->code, PEAR_ERROR_DIE);
  356.                     return false;
  357.                 }
  358.             }
  359.         }
  360.  
  361.         return true;
  362.     }
  363. }
  364. ?>