简体   繁体   中英

PHP - Storing Session in a Database

I am setting up a EC2 cluster with a load balancer. I have seperate DB server which has mysql running on it. I have 3 webservers running, mostly for high availability, and of course its round-robin load balancing it seems, so every page you go to you get a different server which looses your session.

I am trying to setup PHP to store it in the DB. I have setup a table, and setup all the functions (open,close,etc). and I have set:

session_set_save_handler('_open',
                         '_close',
                         '_read',
                         '_write',
                         '_destroy',
                         '_clean');

But when I login or anything on the site I check the table and nothing has been written. I am not sure If i need to change something in the php.ini file. If so what is the value to change?

Thanks!!

EDIT: functions:

function _open(){    
    global $con;
    connect();
} 
    
function _close(){  
    global $con;  
    //mysql_close();
}

function _read($id){    
    global $con;    
    $id = mysql_real_escape_string($id);     
    $sql = "SELECT data FROM sessions WHERE id = '$id'";     
    if ($result = mysql_query($sql, $con)) {        
        if (mysql_num_rows($result)) {            
            $record = mysql_fetch_assoc($result);             
            return $record['data'];        
        }    
    }     
    return '';
}

function _write($id, $data)
{
    global $con;
 
    $access = time();
 
    $id = mysql_real_escape_string($id);
    $access = mysql_real_escape_string($access);
    $data = mysql_real_escape_string($data);
 
    $sql = "REPLACE
            INTO    sessions
            VALUES  ('$id', '$access', '$data')";
 
    return mysql_query($sql, $con);
}

function _destroy($id)
{
   global $con;
    $id = mysql_real_escape_string($id);
    $sql = "DELETE
            FROM   sessions
            WHERE  id = '$id'";
    return mysql_query($sql, $con);
}

function _clean($max)
{
    global $con;
 
    $old = time() - $max;
    $old = mysql_real_escape_string($old);
 
    $sql = "DELETE
            FROM   sessions
            WHERE  access < '$old'";
 
    return mysql_query($sql, $con);
}

session_set_save_handler('_open',
                         '_close',
                         '_read',
                         '_write',
                         '_destroy',
                         '_clean');

The function you're using will interrupt the normal session function and insert your code in to act, then carry on with other internal functions.

In the functions where you aren't really doing anything session-wise (things like '_open' and '_close'), you need return something to carry on the command or it will just die right there.

Example:

function _open($save_path, $session_name){    
    global $con;
    connect();

    return true; //Do nothing but carry on
} 

function _close(){  
    global $con;  
    //mysql_close();

    return true; //Do nothing but carry on
}

Really this is not the answer to your question, but if you need really high availability I can suggest that storing sessions in mysql is not a good method.

A better practice: Put your sessions in memcache. Memcache server it's easy to install. Memcache client is easy to install and php support storing session in memcache without programming!!! Memcache store data in memory, not in disk and it's faster.

Here you can view a good post about this: http://kevin.vanzonneveld.net/techblog/article/enhance_php_session_management/

Luck!!

How come you can't use cookies? and just have the script check if the cookies is present then read the value's from there. Unless security is an issue .. I suggest cookies over sessions for cheap scalability ..Writing session's in the database won't be good and will probably result in expensive queries being ran for no reason.

The best database for sessions is going to be something like Redis or MonogDB and not MySQL and not memcached. You could use memcached depending on how much traffic you get, but Redis or MongoDB is a much more scalable database. Also, since you're on EC2, you may want to look at Amazon SimpleDB. It's a key/value store so it should lend itself well to sessions.

I'd personally run with MongoDB because not only can you store your sessions there, but you can take what you do have from MySQL and cache it there too as well as store other data in Mongo...Or just think about converting your site's database altogether because you'll probably fall in love with MongoDB =)

You can also look into the settings of HAProxy under Application Cookies. That may help you too.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM