SitePoint Sponsor

User Tag List

Results 1 to 9 of 9
  1. #1
    SitePoint Member
    Join Date
    Jun 2004
    Location
    Paris
    Posts
    21
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Yet another session class ... which bugs

    Hi,

    I've written another session class. Some features were taken from some posts on this forum. But the class sometimes bugs when the cookie contains the session_name while the session isn't stored in the database: then serialized datas aren't updated despite my $this->is_new_session flag.

    There was an issue with closing the session with an sql INSERT query and checking if it returns an error about the PRIMARY key (then UPDATE if this error is thrown), but I can't do this since I do error handling in my whole website, including what queries ADOdb.

    Thanks for your help.

    Code:
    CREATE TABLE `sessions` (
      `session_id` varchar(32) NOT NULL default '',
      `data` text NOT NULL,
      `timestamp` timestamp(14) NOT NULL,
      PRIMARY KEY  (`session_id`)
    ) TYPE=MyISAM;
    PHP Code:

    <?php

    define
    ('SESS_USE_COOKIES'true); 
    define('SESS_USE_ONLY_COOKIES'false); 
    define('SESS_MAX_LIFETIME'60*60*24*14); 
    define('SESS_COOKIE_LIFETIME'60*60*24*14); 

    class 
    session
    {
            public   
    $db;
            private  
    $log;
            private  
    $session_data;
            private  
    $is_new_session;

            public function 
    __construct($session_name 's')
            {

                    
    $this->trace("Lancement du constructor");
                    require_once 
    'include/class.db.php';
                    include_once 
    'include/config.inc.php';

                    
    ini_set('session.save_handler''user');
                    
    ini_set('session.name'$session_name);
                    
    ini_set('session.use_cookies'SESS_USE_COOKIES);
                    
    ini_set('session.gc_maxlifetime'SESS_MAX_LIFETIME);
                    
    ini_set('session.use_only_cookies'SESS_USE_ONLY_COOKIES);
                    
    ini_set('session.cookie_lifetime'SESS_COOKIE_LIFETIME);

                    
    $this->connect();

                    
    session_set_save_handler(
                            array(&
    $this'open'),
                            array(&
    $this'close'),
                            array(&
    $this'read'),
                            array(&
    $this'write'),
                            array(&
    $this'destroy'),
                            array(&
    $this'garbageCollection')
                    );

                    if( !isset(
    $_REQUEST[$session_name])){
                            
    session_id$this->createSid() );
                            
    session_start();
                            
    $this->trace"Nouvelle session :" session_id() );
                            
    $this->is_new_session true;
                    }
                    else{
                            
    session_start();
                            
    $this->trace"Session existante: " session_id());
                            
    $this->is_new_session false;
                    }
            }

            public function 
    __get($var)
            {
                    return (!empty(
    $this->session_data[$var])) ? $this->session_data[$var] : false;
            }

            public function 
    __set ($var$value)
            {
                    
    $this->session_data[$var] = $value;
            }

            final function 
    open($path$name)
            {
                    
    $query "
                            SELECT data
                            FROM sessions
                            WHERE session_id = '"
    session_id() ."';";
                    if( 
    $data $this->db->getOne($query) ){
                            
    $unserialized unserialize($data);
                            foreach ( 
    $unserialized as $key => $value ){
                                    
    $this->__set($key$value);
                            }
                            
    $this->trace"Récupération des données de la session");
                    }
                    else{
                            
    $this->is_new_session true;
                    }
                    return 
    true;
            }
             
            final function 
    close()
            {
                    
    $session_data serialize($this->session_data); 

                    if( 
    $this->is_new_session ){
                            
    $this->db->execute("
                                    INSERT INTO sessions ( session_id, data )
                                    VALUES ( '"
    session_id() ."', '$session_data' )");
                            
    $this->trace"Fermeture de la nouvelle session: enregistrement des données");
                    }
                    else{
                            
    $this->db->execute"
                                    UPDATE sessions
                                    SET data = '
    $session_data'
                                    WHERE session_id = '"
    session_id() ."'" );
                            
    $this->trace"Fermeture de la session: mise à jour des données" );
                    }

                    return 
    true;
            }

            final function 
    read($var)
            {
                    return 
    $this->__get( &$var );
            } 

            final function 
    write($var$value)
            {
                    return 
    $this->__set( &$var, &$value);
            } 

            final function 
    destroy()
            {
                    
    $this->db->execute("
                            DELETE FROM sessions
                            WHERE session_id = '"
    session_id() ."'
                    "
    );
                    unset( 
    $this->session_data );
                    
    $cookie session_get_cookie_params();
                    if ( (empty(
    $cookie['domain'])) && (empty($cookie['secure'])) ) {
                            
    setcookie(session_name(), ''time()-3600$cookie['path']);
                    }
                    elseif (empty(
    $cookie['secure'])) {
                            
    setcookie(session_name(), ''time()-3600$cookie['path'], $cookie['domain']);
                    }else {
                            
    setcookie(session_name(), ''time()-3600$cookie['path'], $cookie['domain'], $cookie['secure']);
                    }
                    unset(
    $_COOKIE[session_name()]);
                    
    $this->trace"Destruction de la session "session_id());
                    return 
    true;
            } 

            final function 
    garbageCollection($life)
            {
                    
    $sqldate date("YmdHis"time() - ($life));
                    
    $this->db->execute("DELETE FROM sessions WHERE timestamp > $sqldate");
                    
    $this->trace"Nettoyage des sessions antérieures à $sqldate");
            }

            private function 
    connect()
            {
                    
    $this->db =& database::Singleton();
                    
    $this->trace"Connexion AdoDB établie");
            }

            public function 
    debug()
            {
                    die( 
    "<pre>".htmlspecialchars(print_r$GLOBALStrue ))."</pre>");
            }

            public function 
    createSid()
            {
                    list(
    $usec$sec) = explode(' 'microtime());
                    
    mt_srand((float) $sec + ((float) $usec 100000));
                    return 
    md5(uniqid(mt_rand(), true));

            }

            public function 
    trace($message){
                    
    $this->log[] = "* $message";
            }
    }

  2. #2
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    you might want to declare your table HEAP (as opposed to MyISAM). This means that the table is kept in-memory. if you restart your server once in a while, the content will get flushed, witch means you can do without the garbagecollector.

    you should escape your string, when inserting data. i believe it's the function qstr() in adodb.

  3. #3
    SitePoint Guru
    Join Date
    Dec 2003
    Location
    oz
    Posts
    819
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Is there any reason to declare variabes global that are used only by the session object?

    Why not put it as static variables - or if it will change, in a config file?

  4. #4
    SitePoint Member
    Join Date
    Jun 2004
    Location
    Paris
    Posts
    21
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thank you, but it doesn't solve my problem
    Think I'm gonna drop this session database driven and use native session functions... ;(

  5. #5
    SitePoint Guru
    Join Date
    Dec 2003
    Location
    oz
    Posts
    819
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This is what I use to create custom data store for session handling:
    http://www.zend.com/zend/spotlight/c...8.php#Heading1

  6. #6
    SitePoint Member
    Join Date
    Jun 2004
    Location
    Paris
    Posts
    21
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The _read and _write methods in Zend tutorial aren't good for me: the class queries the database for every session read or write.

    Any other idea?

  7. #7
    SitePoint Member
    Join Date
    Jun 2004
    Location
    Paris
    Posts
    21
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Gasp I found the bug: in the constructor $this->is_new_session is set after session_start(); which calls $this->_open() who first sets $this->is_new_session !

    Then if the session exists but no data is stored in the db $this->is_new_session is overwritten and becomes false !!

    Issue is removing $this->is_new_session = xxx in the constructor.

  8. #8
    does not play well with others frezno's Avatar
    Join Date
    Jan 2003
    Location
    Munich, Germany
    Posts
    1,391
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Yayel
    Yet another session class ... which bugs
    it should 'rock', not 'bug'
    We are the Borg. Resistance is futile. Prepare to be assimilated.
    I'm Pentium of Borg.Division is futile.Prepare to be approximated.

  9. #9
    SitePoint Member
    Join Date
    Jun 2004
    Location
    Paris
    Posts
    21
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You bet it rocks !!!


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •