SitePoint Sponsor

User Tag List

Results 1 to 2 of 2
  1. #1
    From space with love silver trophy
    SpacePhoenix's Avatar
    Join Date
    May 2007
    Location
    Poole, UK
    Posts
    5,032
    Mentioned
    103 Post(s)
    Tagged
    0 Thread(s)

    Database PHP Session Storage & Handling PHP 5.4+

    I've started recoding a site and have got stuck trying to update my session class to work with PHP version 5.4

    PHP Code:
        public function __construct($db) {
            
    $this->db $db;
            
    session_set_save_handler(
                                  array(
    $this'open')
                                , array(
    $this'close')
                                , array(
    $this'read')
                                , array(
    $this'write')
                                , array(
    $this'destroy')
                                , array(
    $this'gc')
                                );
              
    $this->session_expire_time    get_cfg_var("session.gc_maxlifetime");
              
    session_start();
          } 
    That's the constructor for the old session class, this is the new session class as it stands (basically as is from the PHP Anthology book)

    PHP Code:
    <?php
    /**
     *  A session handling class.
     *  A custom session handling class that will save the session 
     *  data to a MySQL database using PDO.  Because of the fixed  
     *  input params to the various functions I sometimes get values  
     *  and do nothing with them.
     * 
     *  Some basic error handling has been implemented with sending 
     *  error messages to the error log.  This can of course be modified 
     *  to work with any error handling logic dictated by the
     *  business rules.
     * 
     *  @param string $sess_table
     *  @param string $sess_db
     *  @param string $sess_db_host
     *  @param string $sess_db_usr
     *  @param string $sess_db_pass
     *  @param mixed $db
     *
     *  @uses PDO
     * 
     *  @todo this has had next to no testing done on it... need to 
     *  write a couple of test scripts for it.
     */
    class session implements SessionHandlerInterface
    {
      
    /**
       * table with session data 
       *
       * @var string
       * @access private
       */
      
    private $sess_table;
      
      
    /**
       * database where session table is 
       * 
       * @var string
       * @access private 
       */
      
    private $sess_db;
      
      
    /**
       * the server where the session database is 
       * 
       * @var string
       * @access private 
       */
      
    private $sess_db_host;
      
      
    /**
       * the user to access the session database 
       * 
       * @var string
       * @access private
       */
      
    private $sess_db_usr;
      
      
    /**
       * the password to access the session database 
       * 
       * @var string
       * @access private 
       */
      
    private $sess_db_pass;
      
      
    /**
       * The database connection object
       * 
       * @param mixed
       * @access private 
       */
      
    private $db;

         
    /**
          * Moves the database access information to class vars.
          * 
          * @param string $sess_table
          * @param string $sess_db
          * @param string $sess_db_host
          * @param string $sess_db_usr
          * @param string $sess_db_pass
          * @access public
          * @return void
          */
      
    public function __construct($db) {
          
    $this->db $db;
          
    $this->sess_table 'ue_user_session';
          
    session_set_save_handler(array($this'open'),
        array(
    $this'close'),
        array(
    $this'read'),
        array(
    $this'write'),
        array(
    $this'destroy'),
        array(
    $this'gc')
    );
    session_start();

      }

         
    /**
          * Open a session by making a connection to the database holding 
          * the session data.
          * Return true or false.  Writes to the default error log if 
          * there is a problem.
          * 
          * @param $open
          * @param $path
          * @access public
          * @return bool 
          */
      
    public function open($path$name)
      {
        return 
    true;
      }

         
    /**
          * close the database connection and end the session 
          * Return true or false.
          * 
          * @access public
          * @return bool
          */
      
    public function close()
      {
        
    $this->db null;
        return 
    true;
      }

         
    /**
          * retrieve the session data from the DB and place it in a string.
          * Must return a string - even an empty one.  Writes to the default 
          * error log if there is a problem.
          * 
          * @param mixed $sess_id
          * @access public
          * @return string
          */
      
    public function read($sess_id)
      {
        try
        {
          
    $sql "SELECT sess_data FROM {$this->sess_table} WHERE sess_id = :id";
          
    $stmt $this->db->prepare($sql);
          
    $stmt->execute(array(':id'=>$sess_id));
          
    $res $stmt->fetchAll(PDO::FETCH_ASSOC);
        }
        catch (
    PDOException $e)
        { 
          
    error_log('Error reading the session data table in the session reading method.');
          
    error_log(' Query with error: '.$sql);
          
    error_log(' Reason given:'.$e->getMessage()."\n");
          return 
    ''
        }
        if (
    count($res) > 0)
        {   
          return isset(
    $res[0]['sess_data']) ? $res[0]['sess_data'] : '';
        }
        else
        {
          return 
    '';
        }
      }

         
    /**
          * Insert or update session data in the DB.
          * Return true or false.  Writes to the default error log if 
          * there is a problem.
          * 
          * @param $sess_id
          * @param $data
          * @access public
          * @return bool
          */
      
    public function write($sess_id$data)
      {
        try
        {
          
    $sql "SELECT sess_data FROM {$this->sess_table} WHERE sess_id = :id";
          
    $stmt $this->db->prepare($sql);
          
    $stmt->execute(array(':id'=>$sess_id));
          
    $res $stmt->fetchAll(PDO::FETCH_ASSOC);
        }
        catch (
    PDOException $e)  
        { 
          
    error_log('Error reading the session data table in the session writing method.');
          
    error_log(' Query with error: '.$sql);
          
    error_log(' Reason given:'.$e->getMessage()."\n");
          return 
    false
        }
        try
        {
          if (
    count($res) > 0
          {
            
    $sql "UPDATE {$this->sess_table} SET sess_last_acc = NOW(), sess_data = :data" .
                
    " WHERE sess_id = :id";
            
    $stmt $this->db->prepare($sql);
            
    $stmt->bindParam(':data'$data);
            
    $stmt->bindParam(':id'$sess_id); 

          }
          else 
          {
            
    $sql ="INSERT INTO {$this->sess_table}(sess_id," .
                
    " sess_start, sess_last_acc," .
                
    " sess_data) VALUES (:id, NOW(), NOW(), :data)";
            
    $stmt $this->db->prepare($sql);
            
    $stmt->bindParam(':id'$sess_id);
            
    $stmt->bindParam(':data'$data); 
          }
          
    $res $stmt->execute();
        }
        catch (
    PDOException $e)
        {
          
    error_log('Error writing to the session data table.');
          
    error_log('Query with error: '.$sql);
          
    error_log('Reason given:'.$e->getMessage()."\n");
          return 
    false;
        }
        return 
    true;
      }

         
    /**
          * Delete the session data row in the database
          * Return true or false.  Writes to the default error log 
          * if there is a problem.
          * 
          * @param $sess_id
          * @access public
          * @return bool
          */
      
    public function destroy($sess_id)
      {
        try
        {
          
    $sql "DELETE FROM {$this->sess_table} WHERE sess_id = :id";
          
    $stmt $this->db->prepare($sql);
          
    $stmt->execute(array(':id'=>$sess_id)); 
        }
        catch (
    PDOException $e)
        {
          
    error_log('Error destroying the session.');
          
    error_log('Query with error: '.$sql);
          
    error_log('Reason given:'.$e->errorMessage()."\n");
          return 
    false;
        }
        return 
    true;
      }

         
    /** 
          * Garbage collector for those that don't properly end 
          * a session or the session times out. Writes to the 
          * default error log if there is a problem.
          * 
          * @param $ttl
          * @access public
          * @return bool
          */
      
    public function gc($ttl)
      {
        
    $end time() - $ttl;
        try
        {
          
    $sql "DELETE FROM {$this->sess_table} WHERE sess_last_acc <:end";
          
    $stmt $this->db->prepare($sql);
          
    $stmt->execute(array(':id'=>$end));
        }
        catch (
    PDOException $e)
        {
          
    error_log('Error with the garbage collection method of the session class.');
          
    error_log('Query with error: '.$sql);
          
    error_log('Reason given:'.$e->getMessage());
          return 
    false;
        }
        
    // may want to consider optimizing the table at a given rate to clean up all the 
        // deletes of a high traffic site - maybe use OPTIMIZE
        
    return true;
      }

      
    /**
      * class desructor
      * because of a few changes in the implementation of the way
      * sessions are closed out (after PHP v. 5.0.5) - when a page  
      * is done we now have to explicitly call the write and close 
      * ourselves.  PHP no longer does it automagically for us.
      * 
      * @param void
      * @return void
      */
      
    public function __destruct()
      {
        
    session_write_close();
      } 
    }
    ?>
    The only real difference that I've made is the change of the class name,

    PHP Code:
    session implements SessionHandlerInterface 
    the use of
    PHP Code:
          $this->db $db;
          
    session_set_save_handler(array($this'open'),
        array(
    $this'close'),
        array(
    $this'read'),
        array(
    $this'write'),
        array(
    $this'destroy'),
        array(
    $this'gc')
    );
    session_start(); 
    in the constructor

    And the removal of the estblishment of the database connection in the open method (I try and use a single instance of the database class (now PDO) throughout the app so that i'm not constantly opening and closing database connections everywhere.

    No matter what I've tried it outright refuses to use the database.
    Community Team Advisor
    Forum Guidelines: Posting FAQ Signatures FAQ Self Promotion FAQ
    Help the Mods: What's Fluff? Report Fluff/Spam to a Moderator

  2. #2
    SitePoint Wizard TheRedDevil's Avatar
    Join Date
    Sep 2004
    Location
    Norway
    Posts
    1,196
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)
    What specific error message do you receive?

    Without knowing that it is difficult for us to understand what is happening.

    For example this could just as well be that the problem is that the database class is destroyed before the session close is handled, compared to that it does not want to use the database. As this is a common problem when you pass along a instance of the connection to the session handler.

    If you dont receive any errors, try adding this right after setting the session handler.

    register_shutdown_function("session_write_close");


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •