SitePoint Sponsor

User Tag List

Results 1 to 7 of 7
  1. #1
    SitePoint Enthusiast
    Join Date
    Jul 2009
    Location
    Austria
    Posts
    43
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    session_set_save_handler error-handling write

    hi!

    A question to session_set_save_handler for PHP-experts.

    If you use session_regenerate_id(true); functions are interpreted in following order:
    1) open
    2) read
    3) prop. gc
    4) destroy
    5) write
    6) close

    error-handling in destroy:
    - If you use trigger_error("error",E_USER_WARNING); (script doesn´t exit), the session-id in the cookie doesn´t change.
    - If you throw an Exception, the session-id in the cookie changes.

    write:
    PHP always creates a new session-id.

    My script:
    PHP Code:
       class SessionHandler {
          private 
    $db;
          private 
    $id;
          public function 
    __construct ($db) {
             
    session_set_save_handler (
                array (
    $this'open'),
                array (
    $this'read'),
                array (
    $this'destroy'),
                array (
    $this'gc'),
                array (
    $this'write'),
                array (
    $this'close')
             );
             
    $this->db $db;
          }
          ...
          public function 
    destroy ($id) {
             try {
                
    $this->db->execute ('DELETE FROM sess WHERE id="'.mysql_real_escape_string ($id).'";');
                return 
    true;
             }
             catch(
    Exception $e) {
                
    trigger_error ('error',E_USER_WARNING); // session-id in the cookie doesn´t change
                
    $this->id $id;                        // info to method write
             
    }
             return 
    false;
          }
          public function 
    write ($id$info) { // $id is the new session-id
             
    ...
             
    $this->db->execute (
                
    'REPLACE INTO sess (id, ´now´, info) VALUES ("'.
                
    mysql_real_escape_string (
                   
    is_null($this->id)
                      ?  
    $id       // new PHP-generated session-id
                      
    :  $this->id // old session-id (in case of an error in method destroy)
                
    ).'", NOW(), "'.mysql_real_escape_string ($info).'");'
             
    );
             ...
          }
          ...
       } 
    If an error in destroy occurs:
    - session-id in the cookie doesn´t change
    - write uses the old session-id

    My question:
    How does PHP create new session-ids? Is there a list? How does PHP guarantee, that each session-id is unique? In case of an error in destroy, write uses the old session-id. But PHP has already created an new session-id. What happens with the old session-id? Is this session-id still unique? Or could it happen, that more than one user get this (old) session-id?

  2. #2
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2008
    Posts
    5,757
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by blubb View Post

    My question:
    How does PHP create new session-ids? Is there a list? How does PHP guarantee, that each session-id is unique? In case of an error in destroy, write uses the old session-id. But PHP has already created an new session-id. What happens with the old session-id? Is this session-id still unique? Or could it happen, that more than one user get this (old) session-id?
    The sid is a just a hash, so collisions are possible. It's a hash(md5/sha1/other) of a concatenation of
    remote_addr
    current seconds + microseconds since epoch
    a pseudo random number
    optional extra entropy file

  3. #3
    SitePoint Enthusiast
    Join Date
    Jul 2009
    Location
    Austria
    Posts
    43
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ok. Thats the way session-ids are generated.
    But I would like to know something different.

    Example:

    Method destroy:
    session-id: 123 (thats the session-id in the session-cookie)
    the DELETE in destroy fails => an error is triggered => $this->id = 123

    Method write:
    then (at the end of the script) the write-method is executed
    session-id: 456 (the new session-id generated by session_regenerate_id) *)
    I don´t work with 456 (new session-id), but with 123(!!!) (the old session-id) *)

    I don´t know, weather PHP still knows session-id 123. If there is a list in PHP, it could look like:
    abc ... user a
    def ... user b
    456 ... the user in my example (456 is the new session-id generated by session_regenerate_id)

    But my list (database-entries) in MySQL looks like:
    abc ... user a
    def ... user b
    123 ... the user in my example (123 is the old session-id)

    Is there such a list in PHP? How does this list look like, if an error occurs in method destroy and i dont use the new session-id?

    If PHP doesn´t know session-id 123 any more, another user could get this session-id => new PHP-list:
    abc ... user a
    def ... user b
    456 ... the user in my example (but his cookie-session-id is still 123(!!!), as i don´t use the new session-id 456)
    123 ... the new user
    4 entries

    But my MySQL-list still looks like:
    abc ... user a
    def ... user b
    123 ... the user in my example
    3(!!!) entries

    SO 2 USERS WORK WITH THE SAME MYSQL-SESSION-ID 123?!

    *) EDIT
    Sorry... my english isn´t very good. I hope you understand my question. It´s not easy to explain.
    Last edited by blubb; Jul 2, 2009 at 09:31.

  4. #4
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2008
    Posts
    5,757
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    There isn't any list aside from the implicit list in your storage medium. For example, the directory which holds the files, or the database which holds the records.

    when php generates a session id, it does not consult the list to check if the id its generating already exists. The probability of collision is very low, and it just assumes collision won't happen.

    So yes, you could have 2 users in your situation. Then again, no failure needs to occur for it to happen.

  5. #5
    SitePoint Enthusiast
    Join Date
    Jul 2009
    Location
    Austria
    Posts
    43
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Is ist possible to create unique session-id´s? Could a MySQL-autoincrement-ID (for example a user-ID) help?

  6. #6
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2008
    Posts
    5,757
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The problem I see here is that you don't control how a session id is created. By the time your php code is handed the session id and told to fetch the data for it, you don't know if the session id handed to your code was a result of a request for a new session id, or if it's intended as a continuation of an existing session.

    A custom session module gets the ability to takeover the process of creating the session id, if it wishes. But you have to write that in c.

  7. #7
    SitePoint Enthusiast
    Join Date
    Jul 2009
    Location
    Austria
    Posts
    43
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I don´t know c
    Really very difficult to program a good session-handler!!!
    Maybe that´s the reason, why I can´t find any code (with error-handling) in the internet (german and english websites).


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
  •