Skip to content

Instantly share code, notes, and snippets.

@mindplay-dk
Last active August 26, 2024 23:46
Show Gist options
  • Select an option

  • Save mindplay-dk/623bdd50c1b4c0553cd3 to your computer and use it in GitHub Desktop.

Select an option

Save mindplay-dk/623bdd50c1b4c0553cd3 to your computer and use it in GitHub Desktop.

Revisions

  1. mindplay-dk revised this gist Aug 3, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion session-life-cycle.md
    Original file line number Diff line number Diff line change
    @@ -124,7 +124,7 @@ in the wrong order, the calls to `read()` and `write()` will be made with two di
    session IDs.

    ```PHP
    session_id(sha('my custom id'));
    session_id(sha1('my custom id'));
    session_start();
    # SessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    # SessionHandler::read('b9361e543a36b9318334f618c3645ae270f773b6')
  2. mindplay-dk revised this gist Aug 3, 2015. 1 changed file with 20 additions and 0 deletions.
    20 changes: 20 additions & 0 deletions session-life-cycle.md
    Original file line number Diff line number Diff line change
    @@ -113,6 +113,26 @@ session_write_close();
    # SessionHandler::close()
    ```

    #### Custom session ID

    Note that manually changing the current session ID using `session_id($id)` is only
    effective if done *before* calling `session_start()` - if called afterwards, it will
    "set" the session ID, and will invoke `write()` with the new session ID, however, it
    will never set the cookie, which means that, upon the next request, the session ID (and
    session contents) will simply go back to the previous one. Also note, if you do this
    in the wrong order, the calls to `read()` and `write()` will be made with two different
    session IDs.

    ```PHP
    session_id(sha('my custom id'));
    session_start();
    # SessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    # SessionHandler::read('b9361e543a36b9318334f618c3645ae270f773b6')
    session_write_close();
    # SessionHandler::write('b9361e543a36b9318334f618c3645ae270f773b6', 'a:0:{}')
    # SessionHandler::close()
    ```

    #### Destruction

    Calling `session_destroy()` will trigger calls to both `destroy()` and `close()` in
  3. mindplay-dk revised this gist Aug 3, 2015. 1 changed file with 6 additions and 6 deletions.
    12 changes: 6 additions & 6 deletions session-life-cycle.md
    Original file line number Diff line number Diff line change
    @@ -103,14 +103,14 @@ you don't accidentally open more than one connection.)

    ```PHP
    session_start()
    # mindplay\session\MockSessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    # mindplay\session\MockSessionHandler::read('ui4odihluc5nkc1oh4gftlgtd7')
    # SessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    # SessionHandler::read('ui4odihluc5nkc1oh4gftlgtd7')
    session_reset()
    # mindplay\session\MockSessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    # mindplay\session\MockSessionHandler::read('ui4odihluc5nkc1oh4gftlgtd7')
    # SessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    # SessionHandler::read('ui4odihluc5nkc1oh4gftlgtd7')
    session_write_close();
    # mindplay\session\MockSessionHandler::write('ui4odihluc5nkc1oh4gftlgtd7', 'foo|s:3:"bar";')
    # mindplay\session\MockSessionHandler::close()
    # SessionHandler::write('ui4odihluc5nkc1oh4gftlgtd7', 'foo|s:3:"bar";')
    # SessionHandler::close()
    ```

    #### Destruction
  4. mindplay-dk revised this gist Aug 3, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion session-life-cycle.md
    Original file line number Diff line number Diff line change
    @@ -31,7 +31,7 @@ session data on access, your best bet may be to bootstrap your applicatio with a
    to `ini_set('session.serialize_handler', 'php_serialize')` which will switch to
    normal serialization compatible with [serialize](http://php.net/serialize) and
    [unserialize](http://php.net/unserialize). (note that this feature is only available
    in PHP 5.5.4 and later.)
    in PHP versions starting from 5.5.4.)

    ```PHP
    session_start();
  5. mindplay-dk revised this gist Aug 3, 2015. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion session-life-cycle.md
    Original file line number Diff line number Diff line change
    @@ -30,7 +30,8 @@ the appropriate function for that format, decodes the data and writes it directl
    session data on access, your best bet may be to bootstrap your applicatio with a call
    to `ini_set('session.serialize_handler', 'php_serialize')` which will switch to
    normal serialization compatible with [serialize](http://php.net/serialize) and
    [unserialize](http://php.net/unserialize).
    [unserialize](http://php.net/unserialize). (note that this feature is only available
    in PHP 5.5.4 and later.)

    ```PHP
    session_start();
  6. mindplay-dk revised this gist Aug 3, 2015. 1 changed file with 9 additions and 2 deletions.
    11 changes: 9 additions & 2 deletions session-life-cycle.md
    Original file line number Diff line number Diff line change
    @@ -22,8 +22,15 @@ session handler likely uses something other than files, you can safely ignore th

    Also note that the actual content of `$_SESSION` has already been serialized at the
    point where PHP calls `write()` - if you need access to the session data for some reason
    (such as wishing to encode it in a different format) you can
    [unserialize](http://php.net/unserialize) the data.
    (such as wishing to encode it in a different format) you can *not* simply
    [unserialize](http://php.net/unserialize) the data, as it isn't encoded in the normal
    serialization format; unfortunately, [session_decode()](http://php.net/session_decode),
    the appropriate function for that format, decodes the data and writes it directly to
    `$_SESSION`, which probably isn't what you want either, so if you do need access to
    session data on access, your best bet may be to bootstrap your applicatio with a call
    to `ini_set('session.serialize_handler', 'php_serialize')` which will switch to
    normal serialization compatible with [serialize](http://php.net/serialize) and
    [unserialize](http://php.net/unserialize).

    ```PHP
    session_start();
  7. mindplay-dk revised this gist Aug 3, 2015. 1 changed file with 88 additions and 3 deletions.
    91 changes: 88 additions & 3 deletions session-life-cycle.md
    Original file line number Diff line number Diff line change
    @@ -10,10 +10,20 @@ resulting calls being made to a custom session-handler registed using

    Output on the left side (from `echo` statements) is indicated by an extra level of indentation.

    ### Open, write and close
    #### Open, write and close

    When you start a new session, and no session is active, `create_sid()` is called, and should
    return the session ID used in subsequent calls to `read()` and `write()`.
    return the new session ID, which PHP will return to the client in a cookie, and use in
    future calls to `read()` and `write()`.

    Note the arguments to `open()` which includes the absolute root path to the folder
    where PHP's standard file session handler normally stores the data - as your custom
    session handler likely uses something other than files, you can safely ignore this.

    Also note that the actual content of `$_SESSION` has already been serialized at the
    point where PHP calls `write()` - if you need access to the session data for some reason
    (such as wishing to encode it in a different format) you can
    [unserialize](http://php.net/unserialize) the data.

    ```PHP
    session_start();
    @@ -26,6 +36,13 @@ session_write_close();
    # SessionHandler::close()
    ```

    #### Resume, read and close

    Note that `write()` will be called, regardless of whether or not any changes were actually
    made to the contents of `$_SESSION` - you may be able to optimize this internally in your
    custom handler and avoid a redundant write; with certain storage back-ends, for example,
    you may be able to "touch" a key/value and avoid the overhead of re-writing the same data.

    ```PHP
    session_start();
    # SessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    @@ -37,6 +54,19 @@ session_write_close();
    # SessionHandler::close()
    ```

    #### Open, regenerate and write

    If a call to [session_regenerate_id()](http://php.net/session_regenerate_id) is made,
    `create_sid()` will be called again to create a new session ID.

    Note that `destroy()` isn't called for the old session ID, which means the previous
    session ID and associated data isn't disposed! - I'm uncertain as ti whether this is
    "by design", and it seems like this could be a potential (minor) security issue, as
    you end up effectively with two identical, distinct, valid sessions. For some reason,
    the user needs to call `session_regenerate_id(true)` to explicitly ask for the old
    session ID to be destroyed, which would generate an extra call to `destroy()` not
    shown in the following example.

    ```PHP
    session_start();
    # SessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    @@ -50,11 +80,45 @@ session_write_close();
    # SessionHandler::close()
    ```

    #### Session reset

    Note that a call to `session_reset()` without a prior call to `session_start()` will result
    in no calls being made to the session handler, whatsoever; apparently, this is by design,
    as neither `session_reset()` or `session_write_close()` will issue any notice or warning.

    Assuming a session has been started, resetting the session will result in both another
    call to `open()` and `read()` in your custom session handler, so be prepared for that.
    (that is, do not expect synchronous calls to `open()` and `close()` during the lifecycle
    of a script - you could be getting more than one call to `open()`, so you will want to
    check in your session handler if the connection to your back-end is already open, so
    you don't accidentally open more than one connection.)

    ```PHP
    session_reset();
    session_start()
    # mindplay\session\MockSessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    # mindplay\session\MockSessionHandler::read('ui4odihluc5nkc1oh4gftlgtd7')
    session_reset()
    # mindplay\session\MockSessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    # mindplay\session\MockSessionHandler::read('ui4odihluc5nkc1oh4gftlgtd7')
    session_write_close();
    # mindplay\session\MockSessionHandler::write('ui4odihluc5nkc1oh4gftlgtd7', 'foo|s:3:"bar";')
    # mindplay\session\MockSessionHandler::close()
    ```

    #### Destruction

    Calling `session_destroy()` will trigger calls to both `destroy()` and `close()` in
    your session handler.

    What can be pretty confusing about session management here, is that, while a call
    to `session_destroy()` does trigger the call to `destroy()`, causing your handler to
    wipe out the data stored for the session, it does *not* generate a new session ID,
    *nor* does it clear the current state of `$_SESSION` from memory. If you were to
    make another call to `session_start()` *after* calling `session_destroy()`, at *this*
    point the contents of `$_SESSION` is wiped out, as this causes subsequent calls to
    `open()` and `read()`, with the *same* session ID, which your handler was just told
    to erase - thus loading an empty session state into a "new" session with the same ID.

    ```PHP
    session_start();
    # SessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    @@ -63,3 +127,24 @@ session_destroy();
    # SessionHandler::destroy('dp1srap0fn9isne4na6mm83mt4')
    # SessionHandler::close()
    ```

    ### In Summary

    The simplest way to think about custom session handlers, is to avoid thinking
    of them as objects with instance methods, although that happens to be how it's
    implemented - instead, think of the methods as being static; or in other words,
    avoid state in your implementation, with the exception of accidental state (for
    optimization/caching purposes), and bear in mind, the original API for custom
    session handlers was a set of individual functions, essentially the analog to
    a set of static methods, not to an object.

    In other words, it's simpler not to make any assumptions about the order in
    which any of the methods are going to be called, how many times they are going
    to be called, or with what arguments - implement every individual method as
    though you had no previous knowledge of what had already been called, and with
    no expectation of any subsequent calls. The only exception being, as mentioned,
    accidental state, e.g. from caching.

    Do not leave any operation half done.

    Good luck.
  8. mindplay-dk revised this gist Aug 3, 2015. 1 changed file with 6 additions and 7 deletions.
    13 changes: 6 additions & 7 deletions session-life-cycle.md
    Original file line number Diff line number Diff line change
    @@ -2,17 +2,20 @@ This page provides a full overview of PHP's [SessionHandler](http://php.net/manu
    life-cycle - this was generated by a set of test-scripts, in order to provide an exact overview of when and
    what you can expect will be called in your custom `SessionHandler` implementation.

    The `<?php` tag in the following indicates the start of a new script request made by a client with cookies
    enabled.
    Each example is a separate script being run by a client with cookies enabled.

    To the left, you can see the function being called in your script, and to the right, you can see the
    resulting calls being made to a custom session-handler registed using
    [session_set_save_handler()](http://php.net/manual/en/function.session-set-save-handler.php).

    Output on the left side (from `echo` statements) is indicated by an extra level of indentation.

    ### Open, write and close

    When you start a new session, and no session is active, `create_sid()` is called, and should
    return the session ID used in subsequent calls to `read()` and `write()`.

    ```PHP
    <?php
    session_start();
    # SessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    # SessionHandler::create_sid()
    @@ -24,7 +27,6 @@ session_write_close();
    ```

    ```PHP
    <?php
    session_start();
    # SessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    # SessionHandler::read('f57cvufkbu6qgfiqkksuagl257')
    @@ -36,7 +38,6 @@ session_write_close();
    ```

    ```PHP
    <?php
    session_start();
    # SessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    # SessionHandler::read('f57cvufkbu6qgfiqkksuagl257')
    @@ -50,13 +51,11 @@ session_write_close();
    ```

    ```PHP
    <?php
    session_reset();
    session_write_close();
    ```

    ```PHP
    <?php
    session_start();
    # SessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    # SessionHandler::read('dp1srap0fn9isne4na6mm83mt4')
  9. mindplay-dk revised this gist Aug 3, 2015. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion session-life-cycle.md
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,8 @@ This page provides a full overview of PHP's [SessionHandler](http://php.net/manu
    life-cycle - this was generated by a set of test-scripts, in order to provide an exact overview of when and
    what you can expect will be called in your custom `SessionHandler` implementation.

    The `<?php` tag in the following indicates the start of a new script being called by a client with cookies.
    The `<?php` tag in the following indicates the start of a new script request made by a client with cookies
    enabled.

    To the left, you can see the function being called in your script, and to the right, you can see the
    resulting calls being made to a custom session-handler registed using
  10. mindplay-dk revised this gist Aug 3, 2015. 1 changed file with 18 additions and 18 deletions.
    36 changes: 18 additions & 18 deletions session-life-cycle.md
    Original file line number Diff line number Diff line change
    @@ -13,39 +13,39 @@ Output on the left side (from `echo` statements) is indicated by an extra level
    ```PHP
    <?php
    session_start();
    # SessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    # SessionHandler::create_sid()
    # SessionHandler::read('f57cvufkbu6qgfiqkksuagl257')
    # SessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    # SessionHandler::create_sid()
    # SessionHandler::read('f57cvufkbu6qgfiqkksuagl257')
    $_SESSION['foo'] = 'bar';
    session_write_close();
    # SessionHandler::write('f57cvufkbu6qgfiqkksuagl257', 'foo|s:3:"bar";')
    # SessionHandler::close()
    # SessionHandler::write('f57cvufkbu6qgfiqkksuagl257', 'foo|s:3:"bar";')
    # SessionHandler::close()
    ```

    ```PHP
    <?php
    session_start();
    # SessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    # SessionHandler::read('f57cvufkbu6qgfiqkksuagl257')
    # SessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    # SessionHandler::read('f57cvufkbu6qgfiqkksuagl257')
    echo $_SESSION['foo'];
    bar
    session_write_close();
    # SessionHandler::write('f57cvufkbu6qgfiqkksuagl257', 'foo|s:3:"bar";')
    # SessionHandler::close()
    # SessionHandler::write('f57cvufkbu6qgfiqkksuagl257', 'foo|s:3:"bar";')
    # SessionHandler::close()
    ```

    ```PHP
    <?php
    session_start();
    # SessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    # SessionHandler::read('f57cvufkbu6qgfiqkksuagl257')
    # SessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    # SessionHandler::read('f57cvufkbu6qgfiqkksuagl257')
    session_regenerate_id();
    # SessionHandler::create_sid()
    # SessionHandler::create_sid()
    echo $_SESSION['foo'];
    bar
    session_write_close();
    # SessionHandler::write('dp1srap0fn9isne4na6mm83mt4', 'foo|s:3:"bar";')
    # SessionHandler::close()
    # SessionHandler::write('dp1srap0fn9isne4na6mm83mt4', 'foo|s:3:"bar";')
    # SessionHandler::close()
    ```

    ```PHP
    @@ -57,9 +57,9 @@ session_write_close();
    ```PHP
    <?php
    session_start();
    # SessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    # SessionHandler::read('dp1srap0fn9isne4na6mm83mt4')
    # SessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    # SessionHandler::read('dp1srap0fn9isne4na6mm83mt4')
    session_destroy();
    # SessionHandler::destroy('dp1srap0fn9isne4na6mm83mt4')
    # SessionHandler::close()
    # SessionHandler::destroy('dp1srap0fn9isne4na6mm83mt4')
    # SessionHandler::close()
    ```
  11. mindplay-dk revised this gist Aug 3, 2015. 1 changed file with 53 additions and 43 deletions.
    96 changes: 53 additions & 43 deletions session-life-cycle.md
    Original file line number Diff line number Diff line change
    @@ -10,46 +10,56 @@ resulting calls being made to a custom session-handler registed using

    Output on the left side (from `echo` statements) is indicated by an extra level of indentation.

    <?php
    session_start();
    SessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    SessionHandler::create_sid()
    SessionHandler::read('f57cvufkbu6qgfiqkksuagl257')
    $_SESSION['foo'] = 'bar';
    session_write_close();
    SessionHandler::write('f57cvufkbu6qgfiqkksuagl257', 'foo|s:3:"bar";')
    SessionHandler::close()

    <?php
    session_start();
    SessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    SessionHandler::read('f57cvufkbu6qgfiqkksuagl257')
    echo $_SESSION['foo'];
    bar
    session_write_close();
    SessionHandler::write('f57cvufkbu6qgfiqkksuagl257', 'foo|s:3:"bar";')
    SessionHandler::close()

    <?php
    session_start();
    SessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    SessionHandler::read('f57cvufkbu6qgfiqkksuagl257')
    session_regenerate_id();
    SessionHandler::create_sid()
    echo $_SESSION['foo'];
    bar
    session_write_close();
    SessionHandler::write('dp1srap0fn9isne4na6mm83mt4', 'foo|s:3:"bar";')
    SessionHandler::close()

    <?php
    session_reset();
    session_write_close();

    <?php
    session_start();
    SessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    SessionHandler::read('dp1srap0fn9isne4na6mm83mt4')
    session_destroy();
    SessionHandler::destroy('dp1srap0fn9isne4na6mm83mt4')
    SessionHandler::close()
    ```PHP
    <?php
    session_start();
    # SessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    # SessionHandler::create_sid()
    # SessionHandler::read('f57cvufkbu6qgfiqkksuagl257')
    $_SESSION['foo'] = 'bar';
    session_write_close();
    # SessionHandler::write('f57cvufkbu6qgfiqkksuagl257', 'foo|s:3:"bar";')
    # SessionHandler::close()
    ```

    ```PHP
    <?php
    session_start();
    # SessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    # SessionHandler::read('f57cvufkbu6qgfiqkksuagl257')
    echo $_SESSION['foo'];
    bar
    session_write_close();
    # SessionHandler::write('f57cvufkbu6qgfiqkksuagl257', 'foo|s:3:"bar";')
    # SessionHandler::close()
    ```

    ```PHP
    <?php
    session_start();
    # SessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    # SessionHandler::read('f57cvufkbu6qgfiqkksuagl257')
    session_regenerate_id();
    # SessionHandler::create_sid()
    echo $_SESSION['foo'];
    bar
    session_write_close();
    # SessionHandler::write('dp1srap0fn9isne4na6mm83mt4', 'foo|s:3:"bar";')
    # SessionHandler::close()
    ```

    ```PHP
    <?php
    session_reset();
    session_write_close();
    ```

    ```PHP
    <?php
    session_start();
    # SessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    # SessionHandler::read('dp1srap0fn9isne4na6mm83mt4')
    session_destroy();
    # SessionHandler::destroy('dp1srap0fn9isne4na6mm83mt4')
    # SessionHandler::close()
    ```
  12. mindplay-dk created this gist Aug 3, 2015.
    55 changes: 55 additions & 0 deletions session-life-cycle.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,55 @@
    This page provides a full overview of PHP's [SessionHandler](http://php.net/manual/en/class.sessionhandler.php)
    life-cycle - this was generated by a set of test-scripts, in order to provide an exact overview of when and
    what you can expect will be called in your custom `SessionHandler` implementation.

    The `<?php` tag in the following indicates the start of a new script being called by a client with cookies.

    To the left, you can see the function being called in your script, and to the right, you can see the
    resulting calls being made to a custom session-handler registed using
    [session_set_save_handler()](http://php.net/manual/en/function.session-set-save-handler.php).

    Output on the left side (from `echo` statements) is indicated by an extra level of indentation.

    <?php
    session_start();
    SessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    SessionHandler::create_sid()
    SessionHandler::read('f57cvufkbu6qgfiqkksuagl257')
    $_SESSION['foo'] = 'bar';
    session_write_close();
    SessionHandler::write('f57cvufkbu6qgfiqkksuagl257', 'foo|s:3:"bar";')
    SessionHandler::close()

    <?php
    session_start();
    SessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    SessionHandler::read('f57cvufkbu6qgfiqkksuagl257')
    echo $_SESSION['foo'];
    bar
    session_write_close();
    SessionHandler::write('f57cvufkbu6qgfiqkksuagl257', 'foo|s:3:"bar";')
    SessionHandler::close()

    <?php
    session_start();
    SessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    SessionHandler::read('f57cvufkbu6qgfiqkksuagl257')
    session_regenerate_id();
    SessionHandler::create_sid()
    echo $_SESSION['foo'];
    bar
    session_write_close();
    SessionHandler::write('dp1srap0fn9isne4na6mm83mt4', 'foo|s:3:"bar";')
    SessionHandler::close()

    <?php
    session_reset();
    session_write_close();

    <?php
    session_start();
    SessionHandler::open('C:\\server\\temp', 'PHPSESSID')
    SessionHandler::read('dp1srap0fn9isne4na6mm83mt4')
    session_destroy();
    SessionHandler::destroy('dp1srap0fn9isne4na6mm83mt4')
    SessionHandler::close()