views:

98

answers:

1

Hi guys, I want to store all my sessions in a DB and have read up on this and implemented the following class:

<?php
/**
* This class handles users sessions and stores the session in the DB rather than in a file. This way stops any 
* shared host security problems that could potentially happen. 
*/
class sessionHandler {

    /**
    * Initial constructor which takes the database object as a param, to do all the database stuff
    * @param object $db The datase object
    */
    public function __construct ($db) {
        $this->db = $db;
        $this->setHandler();    
    }

    function setHandler() {

        session_set_save_handler(array(&$this, "open"),
                                array(&$this, "close"),
                                array(&$this, "read"),
                                array(&$this, "write"),
                                array(&$this, "destroy"),
                                array(&$this, "clean")
                               );           
    }

    /**
    * Initiate a database object if necessary
    */
    function open() {
        $this->db->connect();
    }

    /**
    * Write session id and data to the database
    * @param string $id The hashed 32 char session id, unique to a user
    * @param string $data Serialized session array from the unique session
    * @return id The newly inserted ID of the database
    */
    function write($id, $data) { 
        $access = time();
        $dateAdded = date("Y-m-d G:i:s");

        $this->db->wrapper->where(array("sessionId"=>$id));
        $this->db->query($this->db->wrapper->delete(__CLASS__));

        //fopen a file and store this in it that way we can debug
        $query = $this->db->wrapper->insert(__CLASS__, array("sessionId"=>$id,"dateAdded"=>$dateAdded,"sessionData"=>$data));

        $this->db->query($query);
        return $this->db->insertId();
    }

    /**
    * Retrieve the session data for a given session id
    * @param string $id The hashed 32 char session id, unique to a user
    * @return string The session data found for the given session id
    */
    function read($id) {
        $id = $this->db->wrapper->escape($id);
        $row = $this->db->fetch(1, $this->db->wrapper->get_where(__CLASS__,array("sessionId"=>$id)), array(),false);
        if ($row) {
            return $row['data'];    
        }
        return "";
    }

    /**
    * Delete a session from the database by its unique session id
    * @param string $id The hashed 32 char session id, unique to a user
    * @return integer The number of deleted rows - should only ever be 1
    */
    function destroy($id) { 
        $id = $this->db->wrapper->escape($id);
        $this->db->wrapper->where(array("sessionId"=>$id));
        $this->db->query($this->db->wrapper->delete(__CLASS__));
        return $this->db->affectedRows();
    }

    /**
    * Garage collector which deletes old records in the database, delete sessions that have expired. This is
    * determined by the session.gc_maxlifetime variable in the php.ini 
    * @param integer $max The maximum number of seconds allowed before a session is to be considered expired
    * @return integer The number of deleted rows
    */
    function clean($max) {
        $old = time() - $max;
        $old = $this->db->wrapper->escape($old);
        $this->db->wrapper->where(array("access"=>$old), "<");
        $this->db->query($this->db->wrapper->delete(__CLASS__));
        return $this->db->affectedRows();

    }

    /**
    * Close the database connection once a read / write has been complete
    */
    function close() {
        $this->db->close(); 
    }

    /**
    * End the current session and store session data. 
    */
    public function __destruct(){
        session_write_close();
    }       
}

As you can see in my code, i pass the DB object into the class as a param. My bootstrap file is as follows:

    $db = mogDB::init(); 
    $sh = new sessionHandler($db);

    session_start();

I have used a few of my own classes here so MogDB:init() basically creates a database connection with the right credentials. The wrapper stuff is basically so i dont have to type out sql query after sql query (me being a bit lazy i guess).

But the problem i get is this in my php error log:

08-Apr-2010 17:40:31] PHP Warning:  mysql_insert_id(): 11 is not a valid MySQL-Link resource in /library/mysql.php on line 69 

I have debugged this as much as i can and it seems that when it tries to write the session to the DB, it is failing. I have managed to save the query to a file and that imports fine into the database via phpmyadmin, so its not the query thats the problem.

line 69 in mysql.php is as follows:

68. public function insertId() {
69.     return mysql_insert_id($this->id);
70. }

Any help would be much appreciated Thanks

+1  A: 

After you include the contents of the file /library/mysql.php around line 69 so we can see what is happening there, I am guessing that a small bit of your code is asking for a database handle back to call mysql_insert_id on, and instead, your db api is giving back the actual insertID already...

Zak
i have now added the line 68,69 and 70 in mysql.php
phpNutt
I also get this error aswell before the error aboveWarning: mysql_query(): 11 is not a valid MySQL-Link resource in /library/mysql.php on line 43
phpNutt
right, instead, just return $this->id...
Zak
Sorry Zak, i dont get what you mean, can you explain a little more please
phpNutt
Hi Zak, i have fixed this now but thanks for the advice. I found out that in the write function, i needed to connect to the database again
phpNutt