Jump to content

session_set_save_handler & session issue


mayutaka8985

Recommended Posts

I'm having an issue with sessions and session_set_save_handler.

Note: new at OO PHP

 

I'm using an MVC written mostly from a tutorial and it all seems to be working, except for sessions.

I've got session_set_save_handler as a class SessionHandler. If I include it into the main index page and create an instance, I get an error 'Undefined variable: _SESSION' for my index view file.

If I instead include a global.php file into the main index page and include the session class into the global.php page, and create an instance, the error goes away and session_set_save_handler saves the session variables into my database.

 

(1)On my index page for debugging I've got a var_dump of $_SESSION to see which session variables are set.

 

On my login page I've got a form token that is saved to a session variable. When I go to the login page that session token variable is set and doing a var_dump on the page shows it is indeed being set, however, when I click back to the main index page, the index var_dump(1) shows the session variable is no longer set.

But then if I login it correctly redirects me to a user logged in page and echos the username of the user logged in correctly, but still does not show the form token session variable in the var_dump for index(1). But then if I navigate to the login form page where the form token should be initially set, it now sets it correctly and going to the index page indeed shows the token set.

 

form token being set on login view page:

 

$login_token = $_SESSION['login_token'] = md5(uniqid(mt_rand(),true));

 

var_dump on index page before login (even if I navigate to login page then back to index it remains blank when it should instead show the form token session variable)

array
  empty

 

var_dump on index page after login.

array
  'lu_user' => string 'admin' (length=5)
  'lu_user_id' => string '6' (length=1)
  'user_sess_time' => int 1326544148

 

var_dump on index page after login, navigating to login form page (where login_token is set), then navigating back to index:

 

array
  'lu_user' => string 'admin' (length=5)
  'lu_user_id' => string '6' (length=1)
  'user_sess_time' => int 1326544148
  'login_token' => string 'c260e76dd65f0d9b6e881cfc9a4b33e1' (length=32)

 

Magically the login_token now shows, but only after logging in and setting the other variables. It seems it's not saving the login_token when it's initially set, but only after logging in which it shouldn't be doing.

 

The same issue arises with any other session variables that I set elsewhere (only displayed after user login).

 

If I remove session_set_handler the sessions set correctly but naturally the data is no longer added to the database.

 

If I do var_dump(get_included_files()); it shows the session class is correctly being included.

I was thinking it's an issue with session_start() but if I add that in or try to create another instance of the session class on the other pages, I get an error stating they've already been called and cannot be called again. So then they must be getting called, right?

 

So now I'm thoroughly confused. More code below, sorry for the long post. Hopefully I've provided all necessary information.

 

Index includes global.php, which contains:

 

require 'framework/SessionHandler.php';

$sess = new SessionHandler();

 

 

And the session handler class is (Database class is included into index which is why you cannot see it instantiated here):

 

<?php

class SessionHandler
{
function __construct()
{
	session_set_save_handler
	(
		array(&$this, 'open'),
		array(&$this, 'close'),
		array(&$this, 'read'),
		array(&$this, 'write'),
		array(&$this, 'destroy'),
		array(&$this, 'gc')
	);	

	session_start();

	ini_set('session.gc-maxlifetime', 1800);

	if (isset($_SESSION['lu_user']))
	{
		if (!isset($_SESSION['user_sess_time']))
		{
			$_SESSION['user_sess_time'] = time();
		}
		elseif (time() - $_SESSION['user_sess_time'] > 1800) // 30 mins
		{
   			session_regenerate_id(TRUE);
   			$_SESSION['user_sess_time'] = time();
		}	
	}
}

function open()
{
	$this->db = new Database();
}

function close()
{
	return $this->db = null;
}

function read($id)
{
	$stmt = $this->db->prepare('SELECT * FROM sessions WHERE id = :id');
	$stmt->execute(array(':id' => $id));

	if ($row = $stmt->fetch(PDO::FETCH_ASSOC))
	{
		return $data = $row['data'];
	}
	else
	{
		return '';
	}
}

function write($id, $data)
{
	$access = time();

	if (isset($_SESSION['lu_user']))
	{
		$session_id = session_id();
		$username = $_SESSION['lu_user'];

		$stmt = $this->db->prepare('REPLACE INTO sessions (id, access, data) VALUES (:id, :access, :data)');
		$stmt->execute(array(':id' => $id, ':access' => $access, ':data' => $data));
	}
}

function destroy($id)
{
	if (ini_get("session.use_cookies"))
	{
    		$params = session_get_cookie_params();
    		setcookie(session_name(), '', time() - 42000,
        	$params["path"], $params["domain"],
        	$params["secure"], $params["httponly"]);
	}

	$stmt = $this->db->prepare('DELETE FROM sessions WHERE id = :id');
	$stmt->execute(array(':id' => $id));
}

function gc($max)
{
	$old = time() - $max;

	$stmt = $this->db->prepare('DELETE FROM sessions WHERE access < :old');
	$stmt->execute(array(':old' => $old));
}

function __destruct()
{
	session_write_close();
}
}

Link to comment
Share on other sites

Session variables that change depending on what the url is or disappear/reappear as you navigate around on your site or it seems like you have two different sets of them at the same time - are usually due to the session id cookie only matching some of your host-name/sub-domain variations in your URL and/or specific paths in the URL.

 

Since this seems to correct itself when not using the custom session handler, is there any chance that you are setting any other session parameters (session name, session cookie path, session cookie domain) in your various include files and when you temporarily change the code to stop the custom session handler from being used that you are also either stopping some too restrictive session parameter settings from being used or allowing some more general session parameter settings to be used?

 

It would help if you posted the whole URL that is in the browser's address bar for the pages you described and for the cases where the session variables worked on those pages and where they did not. Alter the domain name if you don't want to post that information, but accurately show any www. or no www. and any paths that are in the URLs.

 

Why are you using a custom session save handler at all? It is only needed in a very limited case (multiple web servers under one domain that need access to the same session data) and since it uses parsed, tokenized, interpreted php code and has extra overhead for the database queries, it is slower than using the built in file session save handler.

 

Edit: Also when switching back and forth between using the custom session save handler and not using it, are you completely closing your browser so that any session id cookie is deleted or if you have set the session cookie lifetime to a non-zero value, are you manually deleting the session id cookie in your browser so that you will start a new session with the matching session data in the correct place?

Link to comment
Share on other sites

It's a test site on my local server so the url for index is: http://localhost:8888/i/index and the url for login is http://localhost:8888/i/login

 

I don't actually need the session_set_save_handler, it's more of a learning experience so I know how to use it should I ever need it.

 

I will try the things you suggested and see if I can pinpoint the issue. Thanks for your suggestions.

Link to comment
Share on other sites

Does your database table have id either as a primary key or an unique index? If not, then the REPLACE query will always insert the data into a new row every time the page ends, but the first row in the table is what will be fetched when the data is read back into your script.

Link to comment
Share on other sites

I checked the id in the database and it's a primary key.

 

I've tried closing and reopening my browser, deleting all cookies etc but that doesn't make a difference. I also searched through all my files and none have any other session data in them, just the usual $_SESSION['sessionname'] = 'content of var';

 

And any created session with $_SESSION on the index page works fine and carries across to other pages, but anything created on the other pages will not carry over...until I login and then suddenly all session variables work across pages and the new variables' data gets appended into the data field in the database.

 

 

Link to comment
Share on other sites

I've had a chance to look closer at your session handler code. You cannot CONDITIONALLY execute the REPLACE query in the write() function.

 

You are trying to integrate the user part of your application code with the low level session call-back functions. That will prevent using session variables for anything else and they won't work in the current code unless you have logged in. You must at least execute the data save logic in the session call-back write() function every time php calls it.

 

 

Link to comment
Share on other sites

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.