Jump to content

Recommended Posts

I have a few questions regarding sessions.

 

I have used them many many many times and have had no problems with them. I am now trying to move my sessions to a database by resetting the save handler using the following code (this is only the class construct)....

 

<?php
function sessionManager() {
$this->db =	new dbConn('test', 0); // instantiate a new db class object
        $this->life_time = get_cfg_var("session.gc_maxlifetime"); // get current lifetime
session_set_save_handler( // start custom session save handler
	array(&$this, "open"), array(&$this, "close"), 
	array(&$this, "read"), array(&$this, "write"), 
	array(&$this, "destroy"), array(&$this, "gc") 
);
}

// the open, close, read, write, destroy, and gc(garbage collection) methods have been truncated.
?>

 

 

So my question is 2 fold here.

 

1. When using this method, should there be session files on the server? When I look in my tmp directory that sessions are stored in, there are session files being created cooresponding to the session id that is created in the db. I was under the impression that session files would not be used when the database is being used.

 

 

2. I have tested that this is indeed writing sessions to the database, however in a login script that I have when the session vars are set (right before a header redirect) they are not being written to the database. I have tried session_commit();  session_write_close(); and they are not working.... Why would this be happening?? I have verified that the above script is in place, and is instantiated before my session_start() is called and that the sessionManager object is instantiated at the time I am trying to save session data.

 

Here is the relevant login script code.

 

<?php
$result = $db->getData("SELECT * FROM users WHERE username='$userName' && password='$password'");
if($result['numRows'] > 0){
	while($row = mysql_fetch_object($result['result'])){
		$firstName = $row->firstName;
		$userId = $row->userId;
	}


/* NONE OF THE FOLLOWING SESSION VARS ARE BEING SAVED */
	$_SESSION['loggedIn'] = 1;
	$_SESSION['userName'] = $firstName;
	$_SESSION['userId'] = $userId; 
	$_SESSION['allowEdit'] = 1;
	header('Location:index.php');
?>

 

Any help is appreciated.

 

Thanks,

 

Nate

Link to comment
https://forums.phpfreaks.com/topic/151197-solved-sessions-in-database-problem/
Share on other sites

You require callback functions for all session actions i.e.

<?php
// override php default session handler 
session_set_save_handler('sessionOpen', 'sessionClose', 'sessionRead', 'sessionWrite', 'sessionDestroy', 'sessionClean');


// open session
function sessionOpen($savePath, $sessionName) {
}

// close session
function sessionClose() {
}

// read session data from database using the sessionId
function sessionRead($key) {
}

// write a session value to database
function sessionWrite($key, $val) {
}

// destroy a session - remove from database
function sessionDestroy($key) {
}

// clean up old sessions - remove all sessions past a certain time
function sessionClean($maxlifetime) {
}
?>

thanks for the reply... but yes I know... there is more to the file.. I just did not post it all... I mentioned that the rest of the methods are there.

 

here is the complete sessions.class.php

 

<?php
class sessionManager {
   var $life_time;
var $db;

function sessionManager() {
	$this->db =	new dbConn('test', 0);
      $this->life_time = get_cfg_var("session.gc_maxlifetime");
session_set_save_handler(
	array(&$this, "open"), array(&$this, "close"), 
	array(&$this, "read"), array(&$this, "write"), 
	array(&$this, "destroy"), array(&$this, "gc") 
);
}
/**
*
*/
   function open( $save_path, $session_name ) {
      global $sess_save_path;
      $sess_save_path = $save_path;
      // Don't need to do anything. Just return TRUE.
      return true;
   }
/**
*
*/
   function close() {
      return true;
   }
/**
*
*/
   function read( $id ) {
      $data = '';
      $time = time();
      $newid = mysql_real_escape_string($id);
      $sql = "SELECT `session_data` FROM `sessions` WHERE `session_id` = '$newid' AND `expires` > $time";
      $rs = $this->db->getData($sql);                           
      $a = $rs['numRows'];
      if($a > 0) {
        $row = mysql_fetch_assoc($rs['result']);
        $data = $row['session_data'];
      }
      return $data;
   }
/**
*
*/
   function write( $id, $data ) {
      // Build query                
      $time = time() + $this->life_time;
      $newid = mysql_real_escape_string($id);
      $newdata = mysql_real_escape_string($data);
      $sql = "REPLACE `sessions`(`session_id`,`session_data`,`expires`) VALUES('$newid','$newdata', $time)";

      $rs = $this->db->rawQuery($sql);
      return TRUE;
   }
/**
*
*/
   function destroy( $id ) {

      // Build query
      $newid = mysql_real_escape_string($id);
      $sql = "DELETE FROM `sessions` WHERE `session_id` = '$newid'";

      db_query($sql);
      return TRUE;
   }
   function gc() {
      $sql = 'DELETE FROM `sessions` WHERE `expires` < UNIX_TIMESTAMP();';
      db_query($sql);
      // Always return TRUE
      return true;
   }

function __destruct(){
	session_write_close();	
}
}
?>

 

I can set some session vars on another page, and they get added to the db... but for some reason when I try to set the sessions on my login page they don't write to the db....  So I have confirmed that it is working, just not on this page.

 

I read that having a header('Location: ......'); could cause an issue and I should use session_write_close(); or session_commit(); .... but those don't force the data to be written.

 

Anyone else??

 

Thanks,

 

Nate

Once you replace the session save handler before every session_start() (and given that you are still seeing session data files being created, is not being done for every script), $_SESSION variables work exactly like they do using the built-in file save handler. If you have one script that $_SESSION variables are not working for, either the custom session save handler is not in place before the session_start() in that file or you have a problem with the session.cookie_path or session.cookie_domain settings and the URL's being using.

 

BTW - The custom session save handler is made up of slow parsed/tokenized/interpreted php code and is between 50 and 100 times slower than using the built-in file save handler that uses complied C code. The only known valid reason for using a custom session save handler is if you need session data to be available between different servers, such as when you have load balanced web servers. The other known problems with using the built-in file save handler are easily solved. What problem are you having that you think using a custom session save handler will solve?

I did that and when I set a session on my /index.php page it writes to the file..... When I try and login, it then creates that file inside /admin and writes the session I set on /index.php....

 

So it is writing properly.... it just will not write those variables.... when I do a print_r($_SESSION) on the admin page right below the session and right above the header('Location:....) it shows them in the session, but it does not keep them.

 

This is the only thing it writes....

 

REPLACE `sessions`(`session_id`,`session_data`,`expires`) VALUES('ljj8emu6rkkuagtso6bnbpkhk0','testing|s:14:\"this is a test\";', 1238078577)

 

I have verified that this session class is active in this page and it should be writing these session vars to the db... but for some reason it is not triggering the write function at this point...

 

Any other ideas?

 

nate

What problem are you having that you think using a custom session save handler will solve?

 

I have 1 place that the session_start is declared and that is included in every file on the site..... so that is not the issue...

 

I figured saving sessions to the database will be more secure.. especially in a shared hosting environment...

 

Also it was a learning experience on how it is done. But mostly thinking about being more secure on a shared hosting environment.

 

Thanks

 

 

Do you have the necessary keys setup in the database table for a REPLACE query to work?

 

The way to secure session data files on a shared web server is to set the session save path to a private folder within your account's folder tree.

I am assuming so. I have a primary key defined. Here is the result of describe sessions

 

Field Type Null    Key           Default Extra

session_id               varchar(100)  NO PRI  

session_data       text           NO   NULL

expires               int(11)   NO   0

 

The custom session handling will work.... when I set a var on /index.php it writes to the db, when I re-set that var on /test.php, it replaces it in the db.

 

I just cannot figure out why it won't write the session vars from the login script. The custom handler is initialized by the time the sessions are attempting to be set, so it should work... but it is not.

 

Nate

It sounds like the session is not being started on that page. If so, a variable named $_SESSION[...] in only a regular array variable. You can echo it... but if it is not part of a valid session, nothing will happen with it. Add the following two lines immediately after your first opening <?php tag -

 

ini_set ("display_errors", "1");
error_reporting(E_ALL);

I got no errors from that, I also did this...

<?php

.......... 
	$_SESSION['allowEdit'] = 1;

	echo session_id(); // gave me ljj8emu6rkkuagtso6bnbpkhk0
	#header('Location:index.php');
}else{...............
?>

 

So I have verified that the session is started, that the custom session handler is included and instantiated. Everything points to "this should be working".... but it is not.

 

Doing a print_r($_SESSION) and echoing the session ID gives me this....

<?php

Array
(
    [token] => aa06cfc2352117728818b3b6e3e75fda5baf5764 // this is a session that is set to ensure the form is submitted the correct way.. and not refreshed.
    [loggedIn] => 1                             // set upon sucessful login
    [userName] => Nathan                   // set upon sucessful login
    [userId] => 1                               // set upon sucessful login
    [allowEdit] => 1                           // set upon sucessful login
    [testing] => This is another test   // set on a different page altogether
)

sessionID: ljj8emu6rkkuagtso6bnbpkhk0

?>

 

 

 

So I am baffled.... it SHOULD be working but it is not..... it works on other pages.. but not on this page.

Any chance that the mysql connection is being closed on that page? Your session save handler has absolutely no error checking, error reporting/logging, or error recovery logic in it to get it to tell you if or when it is not functioning.

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.