views:

543

answers:

2

Hey guys, here's what I'm attempting:

PHP sessions work by default with my configuration, if I just go session_start() and try the standard session increment test it works.

if (!isset($_SESSION['count'])) {
    $_SESSION['count'] = 0;
} else {
    $_SESSION['count']++;
}

However I want to use a MySQL table for session storage. I've put together my sessions.php file with all the functions, copied them right out of a book like a n00b, and the functions work (affect the database) if I call them like regular functions, but using the standard test above does not work. It sets the session for just the page load, and no change in the database. I put a line in each function to log each call, and the log reflects that the functions are being called by session_start().

Here's what my code looks like:

session_module_name("user");
session_set_save_handler("session_open", "session_close", 
"session_read", "session_write", "session_remove", "session_gc");
session_start();

session_open, etc, being the name of my functions. I've even tried another set of functions out of an o'rly example, and got the same results.

Any ideas why? session_register() also yields the same results.
Thanks, guys.

EDIT: here are the actual functions, I apologize for the length, but I log everything in dev.

function session_db(){
    return("my_db_name");
    }
function session_table(){
    return("sessions_table");
    }
function session_log($message){
    if($file = fopen($application["siteroot"] . 'log/session.txt', "a")){
        fwrite($file, date("Y-m-d H:i:s ") . $message . "\n");
        fclose($file);
        }
    }
function session_open($path, $name){
    session_log("session_open");
    return(true);
    }
function session_close(){
    session_log("session_close");
    return(true);
    }
function session_read($id){
    session_log("session_read");
    if(!mysql_select_db(session_db())){
        session_log("session_read select database error: " . mysql_error());
        return(false);
        }
    $sql = "select * from " . session_table() . " where id='" . $id . "'";
    if(!$result = mysql_query($sql)){
        session_log("MySQL error: " . mysql_error() . " with SQL: " . $sql);
        return(false);
        }
    if(mysql_num_rows($result)){
        session_log("MySQL query returned " . mysql_num_rows($result) . "rows.");
        $row = mysql_fetch_assoc($result);
        session_log("session_read returned " . $row["data"]);
        return($row["data"]);
        }
    else{
        session_log("session_read found zero rows with SQL: " . $sql);
        return("");
        }
    }
function session_write($id, $data){
    session_log("session_write");
    if(!mysql_select_db(session_db())){
        session_log("session_write select database error: " . mysql_error());
        return(false);
        }
    $sql = "update " . session_table() . " set data = '" . addslashes($data) . "', time=null";
    if(isset($PHP_AUTH_USER)){
        $sql .= ", user='" . addslashes($PHP_AUTH_USER) . "'";
        }
    $sql .= " where id='" . $id . "'";
    if(!$result = mysql_query($sql)){
        session_log("session_write error " . mysql_error() . " with SQL: " . $sql);
        return(false);
        }
    if(mysql_affected_rows()){
        session_log("session_write update affected " . mysql_affected_rows() . " rows with SQL: " . $sql);
        return(true);
        }
    session_log("session_write updated zero rows with SQL: " .$sql);
    $sql = "insert into " . session_table() . "(data,id) values('" . addslashes($data) . "','" . $id . "')";
    if(!$result = mysql_query($sql)){
        session_log("session_write error " . mysql_error() . "with SQL: " . $sql);
        return(false);
        }
    else{
        session_log("mysql_write inserted with SQL: " . $sql);
        return(true);
        }
    }
function session_remove($id){
    session_log("session_remove");
    if(!mysql_select_db(session_db())){
        session_log("session_remove select database error: " . mysql_error());
        return(false);
        }
    $sql = "delete " . session_table() . " where id='" . $id . "'";
    if($result = mysql_query($sql)){
        session_log("MySQL query delete worked");
        return(true);
        }
    else{
        session_log("MySQL update error: " . mysql_error() . " with SQL: " . $sql);
        return(false);
        }
    }
function session_gc($life){
    session_log("session_gc");
    if(!mysql_select_db(session_db())){
        session_log("session_gc select database error: " . mysql_error());
        return(false);
        }
    $sql = "delete " . session_table() . " where time < '" . date("YmdHis", time() - $life) . "'";
    print("session_gc sql: " . $sql);
    if($result = mysql_query($sql)){
        session_log("session_gc deleted " . mysql_affected_rows() . " rows.");
        return(true);
        }
    else{
        session_log("session_gc error: " . mysql_error() . " with SQL: " . $sql);
        return(false);
        }
    }
A: 

I don't think you need the call to session_module_name, try commenting it out and see what happens.

Neel
It looks like you're right that I don't need to call it, I commented it out and nothing changed. Same results, the session lasts for 1 page load.
Aaron
Try logging the parameters passed into session_write and make sure the id and the session data are the right way around.
Neel
Good call Neel! I should be logging that! Turns out session_write isn't even being called, and that's got to be part of the problem.So if session_start() calls session_open and session_read, why do you suppose a call to register_session or even $_SESSION= wouldn't call session_write?
Aaron
Where are you calling session_set_save_handler() and session_start() and also where are you defining your functions. Stick them as close to the top of your code as possible.
Neel
Well I call them at the bottom of sessions.php, after all the functions are defined. Basically I kept the working session code as is and added the include the line before it.
Aaron
You called it Neel, I had to put session_set_save_handler("session_open", "session_close", "session_read", "session_write", "session_remove", "session_gc"); session_start();As the first two lines. I've been at this issue all day, you saved me!
Aaron
A: 

There are a couple of things...

  1. We might need to see, at the very least, the actual functions.

  2. You probably want to register a shutdown function, your writes are probably being called too late to save to the database.

    register_shutdown_function('session_write_close');

Just to clarify, the reason for the above is that the write and close functions are normally called after objects are destroyed. This call will ensure that these are made before object destruction.

John Cavan