Recently I\'ve noticed that many blank sessions are being created, I\'m not sure why though as I believe I\'m doing everything the correct way.
At the moment we crea
Does session_regenerate_id(true) create a new session file and leave the old session file empty? That is the only reason I can think of for the empty session files?
Calling session_regenerate_id(true) attempts to delete the session file but will return false if it fails to do (see relevant php source code below). For this reason I suggest you verify that your session functions run successfully i.e.
if(!session_start()) {
//log error
}
if(!session_regenerate_id(true)) {
//log error
}
Also check your settings for how frequently your garbage collector runs. Perhaps it runs on a very low probability and you're seeing orphaned sessions accumulate. The settings below will run the garbage collector with 1/100 (1%) probability each time php runs. Try deleting all orphans by setting both values to 1 for a single run and then setting the values to 1/100 like below.
session.gc_probability = 1
session.gc_divisor = 100
Finally, your logout method expires the session cookie on browser close. Try expiring it immediately instead
setcookie('auth', null, -1);
PHP Source for session_regenerate_id
https://github.com/php/php-src/blob/master/ext/session/session.c
Note the call to PS(mod)->s_destroy(&PS(mod_data), PS(id) TSRMLS_CC)
/* {{{ proto bool session_regenerate_id([bool delete_old_session])
Update the current session id with a newly generated one. If delete_old_session is set to true, remove the old session. */
static PHP_FUNCTION(session_regenerate_id)
{
zend_bool del_ses = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &del_ses) == FAILURE) {
return;
}
if (SG(headers_sent) && PS(use_cookies)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot regenerate session id - headers already sent");
RETURN_FALSE;
}
if (PS(session_status) == php_session_active) {
if (PS(id)) {
if (del_ses && PS(mod)->s_destroy(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Session object destruction failed");
RETURN_FALSE;
}
efree(PS(id));
PS(id) = NULL;
}
PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC);
if (PS(id)) {
PS(send_cookie) = 1;
php_session_reset_id(TSRMLS_C);
RETURN_TRUE;
} else {
PS(id) = STR_EMPTY_ALLOC();
}
}
RETURN_FALSE;
}
PS_DESTROY_FUNC
https://github.com/php/php-src/blob/master/ext/session/mod_files.c
Note VCWD_UNLINK which is a command to remove the file from disk.
PS_DESTROY_FUNC(files)
{
char buf[MAXPATHLEN];
PS_FILES_DATA;
if (!ps_files_path_create(buf, sizeof(buf), data, key)) {
return FAILURE;
}
if (data->fd != -1) {
ps_files_close(data);
if (VCWD_UNLINK(buf) == -1) {
/* This is a little safety check for instances when we are dealing with a regenerated session
* that was not yet written to disk. */
if (!VCWD_ACCESS(buf, F_OK)) {
return FAILURE;
}
}
}
return SUCCESS;
}
Just my 2 cents: a user (whether or not logged in) is using the site during a certain time, which is usually called a "session". Would it be a problem to always start a session and keep a session variable to see if someone is authenticated. Right now it seems you try to only start a session if someone is logged in, which adds more overhead than just starting a session and checking a variable for the same behavior.
If you keep the session timeout low, someone is automaticly logged out. Depending on the site traffic, you can set the GC to kick in more often or less often. (see: http://www.php.net/manual/en/session.configuration.php#ini.session.gc-divisor)
If the harddisk is a bottleneck for sessions (too much empy session files etc.), create a small RAMdisk to store session information on.
bool session_regenerate_id([bool $delete_old_session = false]);
view php manual for more information.
session_regenerate_id() will replace the current session id with a new one, and keep the current session information.
the old session file is kept and a new session file is generated every time that session_register_id() is ran. session_register_id() creates a new session with a new session_id but retains the old session information, so yes, your session_register_id() is keeping the old session files to null after updating the information to the new session file.
Shouldn't header("Location: $_SERVER[HTTP_REFERER]"); need to be header("Location: $_SERVER['HTTP_REFERER']"); ? Or is that just something stupid.
EDIT:
According to PHP.net you should use the delete_old_session parameter. Have a look HERE