Jump to content

[SOLVED] custom (database) session handling dropping data


Recommended Posts

I just today copy/modded a custom session handler for use with a database.  however, it seems that it's dropping the session data while the rest of info (stored in the database) stays put just fine. (i'm referring to session_id, ipaddr, expiry time, etc are fine)

 

It currently loses data after a header() request to the same page with a different GET variable set.

Any ideas why it can't hold onto the data?

edit:It seems that my other errors that process through User.php don't stay set either..

 

some code

page: login.php processed by (class) user.php, relevant section:

<?php
          $this->session->set('rcpw_un',$this->un);
          header('Location: '.STARTURL.'login.php?do=cpw');
?>

rcpw_un is confirmed as being set and valid, I have tested it with die() statements btwn set() and header() while checking the database.

 

login.php (user creates its own session instance in it's constructor)

the // ## shows that the var that was just set above, does not stay set.

<?php
  require 'engine/config.php';

switch(true)
{
  //logout if requested
  case (isset($_GET['do']) && $_GET['do'] == 'logout'):
    $user = &new User($db,SECRET,true);
    break;

//--------------------------------------------------------------------------

  //request change password
  case (isset($_GET['do']) && $_GET['do'] == 'cpw'):
    $session=&new Session();
    $un = $session->get('rcpw_un'); // ## this is not staying set

      //require session(un) to be set from login before instantiating
      if(!$un) {
        $session->set('login_error','Please login before accessing that page.');
        //header('Location: ./index.php');
      }
      echo $un;
    
    $rcpw = &new RCPW($un,$session);
    break;

//--------------------------------------------------------------------------

  //regular login
  default:
    $user = &new User($db,SECRET);
    break;

}//switch
?>

 

 

 

extra reference code

And then the session handler and session class for reference:

sessionhandler.php

<?php
class SessionHandler {
   public $maxlifetime;
   public $db;
   public $sess_save_path;
    private $ip;
    private $ua;//useragent

  /**
   *  __construct
   *  reads session max lifetime, sets session save handler
   *
   *  @access public
   */
  public function __construct()
  {
    // Read the maxlifetime setting from PHP
    $this->maxlifetime = get_cfg_var("session.gc_maxlifetime");
    $this->db = MYSQL::get(DB_HOST,DB_UN,DB_PW,DB_DB);
      $this->ip = $_SERVER['REMOTE_ADDR'];
      $this->ua = $_SERVER['HTTP_USER_AGENT'];

    // Register this object as the session handler
    session_set_save_handler( 
      array( $this, "open" ), 
      array( $this, "close" ),
      array( $this, "read" ),
      array( $this, "write"),
      array( $this, "destroy"),
      array( $this, "gc" )
    );

  }//__c



  /**
   *  open
   *  get a database instance
   *  
   *  @access public
   *  @return (boolean) true
   *  @param (string) path
   *  @param (string) name
   */
  public function open($save_path,$session_name)
  {
    $this->sess_save_path = $save_path;

    // Don't need to do anything. Just return TRUE.
    return true;
  }//open



  /**
   * close
   * 
   *  @access public
   *  @return (boolean) true
   */
  public function close()
  {
    return true;
  }



  /**
   *  read
   *  reads stored session data
   *
   *  @access public
   *  @return (mixed) data
   *  @param (string) id
   */
  public function read($id)
  {
    // Set empty result
    $data = '';

    // Fetch session data from the selected database
    $time = time();

      $newid = mysql_real_escape_string($id);
      $sql = "SELECT `session_data` FROM `SESSIONS` WHERE
              `session_id` = '$newid' AND `expires` > $time";

        $result = $this->db->query($sql);
        $a = $this->db->countRows($sql);

           if($a > 0) {
            $row = mysql_fetch_array($result);
              $data = $row['session_data'];
           }

      return $data;
  }//read



  /**
   *  write
   *  write data to a session
   *
   *  @access public
   *  @return (boolean) true
   *  @param (string) id
   *  @param (mixed) data
   */
  public function write( $id, $data ) {
    // Build query                
    $time = time() + $this->maxlifetime;

      $newid = mysql_real_escape_string($id);
      $newdata = mysql_real_escape_string($data);

      $sql = "REPLACE `SESSIONS` 
            (`session_id`,`session_data`,`ipaddr`,`useragent`,`expires`) VALUES
            ('$newid','$newdata','$this->ip','$this->ua',$time)";

         $result = $this->db->query($sql);
         return true;
  }//write



  /**
   *  destroy
   *  cleans up a session by deleting it
   *
   *  @access public
   *  @return (boolean) true
   *  @param (string) id
   */
  public function destroy( $id ) {
    // Build query
    $newid = mysql_real_escape_string($id);
      $sql = "DELETE FROM `SESSIONS` WHERE `session_id` = '$newid'";
        $this->db->query($sql);

      return true;
  }//destroy



  /**
   *  gc
   *  garbage collection
   *
   */
  function gc() {
    // Delete all records who have passed the expiration time
    $sql = "DELETE FROM `SESSIONS` WHERE `expires` < UNIX_TIMESTAMP()";
      $this->db->query($sql);
      
      $opt = "OPTIMIZE TABLE `SESSIONS`";
        $this->db->query($opt);
     // Always return TRUE
     return true;
  }//gc

}//class

/*
CREATE TABLE `SESSIONS` (
  `session_id` varchar(100) NOT NULL default '',
  `session_data` text NOT NULL,
  `expires` int(11) NOT NULL default '0',
  PRIMARY KEY  (`session_id`)
) TYPE=MyISAM;
*/
?>

 

session.php

<?php

class Session extends SessionHandler{

  /**
   *  __construct
   */
  public function __construct()
  {
    parent::__construct();
    session_start();
  }



  /**
   *  set
   *  set a session var
   *
   *  @access public
   *  @return void
   *  @param (str) name
   *  @param (mixed) value
   */
  public function set($name, $value)
  {
    $_SESSION[$name] = $value;
  }



  /**
   *  get
   *  retrieve a session var
   *
   *  @access public
   *  @return value or false
   *  @param (str) name
   */
  public function get($name)
  {
    if(isset($_SESSION[$name])) {
      return $_SESSION[$name];
    }else{
      return false;
    }
  }



  /**
   *  del
   *  unset a session var
   *
   *  @access public
   *  @return void
   *  @param (str) name
   */
  public function del($name)
  {
    unset($_SESSION[$name]);
  }



  /**
   *  destroy
   *  delete session, regenerate id
   *
   *  @access public
   *  @return void
   */
  public function destroy()
  {
    $_SESSION = array();
    session_destroy();
    session_regenerate_id(true);
  }

}//class Session
?>

Is the data ever in the database to begin with?

 

 

Put a line in SessionHandler.write that says "This is being called" or something and see if it's ever called.  If I get bored in a sec I might recreate your DB schema and try to figure out why it's not being saved and or retrieved.

The redirect is probably going to a different path or domain (which is actually a host name, not a domain - www.domain.com vs domain.com) and the session cookie parameters are not setup to cause the cookie to match the resulting path/domain.

 

A custom session save handler is a separate issue. Get your code to work using the built-in file save handler first or if you have already confirmed that the custom session save handler works, than the session save handler code is irrelevant to your problem.

 

A custom session save handler using a database only has a real use if you have multiple load-balanced web servers where different requests by one visitor could be serviced by different servers and you need to make the session data available to all the web servers. Because of the extra overhead of using a php based custom session save handler and the extra overhead of using a database to hold the session data, you should only do this when necessary. The built-in file save handler is much faster (it uses complied code) and any normal problem can be solved by simply changing session settings.

Regarding what PFMaB.. said, I'll take it back to the way I had it.  I appreciate the help, and I will still look into the things you guys brought up in case I need to solve the problem another time.  Many thanks, comments below:

 

@PFMaBiSmAd

-I'll have to look into the domain thing, that would make sense.  I had this working using file based sessions, but I wanted to switch over to database session handling because I'm on a shared server, and I had a feeling the shared session storage area was causing trouble.  I'll have to play with the session_save_path... I didn't really know much about it.

 

@corbin

-Yes, the data was passed to the db.  But I guess I'll go back to the way I had it.  Hopefully you didn't start messing with it too much.

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.