2

I´m trying to setup a custom session safe handler which works so far. But I don´t want to store the data in PHP session format but pure JSON format. How do I have to change read and write functions to en-/decode the php session data to json.

function write($sessionId, $data) { 
    $db = new PDO("mysql:host=myhost;dbname=mydb", "myuser", "mypassword");

    $sql = "INSERT INTO session SET session_id =" . $db->quote($sessionId) . ", session_data =" . $db->quote($data) . " ON DUPLICATE KEY UPDATE session_data =" . $db->quote($data);
    $db->query($sql)
}

function read($sessionId) { 
    $db = new PDO("mysql:host=myhost;dbname=mydb", "myuser", "mypassword");

    $sql = "SELECT session_data FROM session where session_id =" . $db->quote($sessionId);
    $result = $db->query($sql);
    $data = $result->fetchColumn();
    $result->closeCursor();

    return $data;
}

The functions are from following tutorial. The author says:

PHP passes the data in serialized to the write function, and expects it serialized back from the read function, but that doesn’t mean you have to store it that way. You could unserialize the data immediately in the write callback and then perform some action dependent on the data or store it however you wish.

I´ve tried following functions which I thought would do the job?

  • json_encode()
  • json_decode()
  • serialize()
  • unserialize()

EDIT

If I´m not trying to json_encode the data, it´s written into db as expeceted in following format:

auth|b:1;LAST_ACTIVITY|i:1407480463;

1 Answer 1

2

The session data that is passed to the write function is not unserializable.... There are some methods to do the unserialization manually, but they fail at one point or another depending on how complex your session data is. So, here is my solution.

Step 1. Create a new field in your table and name it something like "json" You will have to store both the json data and the php serialized format. You can use the json data however you like, but the $data that is passed into the write function MUST be returned exactly as passed in. And there is no (easy) way to do this correctly. So, instead, just look up the $_SESSION and encode that. Then store both the $data and json encoded version in your table. Your read operation only needs to return the $data that was passed into your write function.

function write($sessionId, $data) {
    $db = new PDO("mysql:host=myhost;dbname=mydb", "myuser", "mypassword");

    // Convert current $_SESSION to json because it hasn't been destroyed yet.
    $json = json_encode($_SESSION);

    $quotedSessId = $db->quote($sessionId);
    $quotedData = $db->quote($data);
    $quotedJson = $db->quote($json);

    $sql = "INSERT INTO session SET session_id = $quotedSessionId, session_data = $quotedData, json = $quotedJson ON DUPLICATE KEY UPDATE session_data = $quotedData, json = $quotedJson";
    $db->query($sql);
}

function read($sessionId) {
    $db = new PDO("mysql:host=myhost;dbname=mydb", "myuser", "mypassword");

    $sql = "SELECT session_data FROM session where session_id =" . $db->quote($sessionId);
    $result = $db->query($sql);

    $result->closeCursor();

    return $data;
}
Sign up to request clarification or add additional context in comments.

7 Comments

thanks for this. yes this is how it should work unfortunately I´m getting "false" in my session coloumn.
What if you don't try to json encode and instead just use the default functions? Do you get a valid serialized string in your column then? Perhaps this will give some insight as to why you are getting false.
yes, if I´m not using json the php session format is written to the db as expected. mhhh but json is also string like php serialized session thought maybe thats the problem, a different data type, mhhh
can you post an example of the php session format that is written to the db when not trying to convert to json?
OK, it looks like the data that's handed to the write function is not in the normal format.... It's still possible, just some things to consider. I am editing my answer now.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.