#67 sessions not compatible with PHP 5.2

Next_Version
closed-fixed
Sessions (4)
5
2006-11-15
2006-11-09
Vygi
No

Hi here,

today I have tried to upgrade my PHP to 5.2 and
immediately after them I have started to get errors:

"Fatal error: Call to a member function execute() on a
non-object in [...]/session/adodb-session.php on line
127"

This line contains indeed an execute statement where
$db_object is not set when using PHP 5.2:

$db_object->execute("UPDATE $table SET [...] ");

95th line of same file says:

$db_object =& $GLOBALS['ADODB_SESS_CONN'];

I have tried to print_r($GLOBALS) and see that
"ADODB_SESS_CONN =>" (is empty).

After switching back to PHP 5.1 everything is right
again.

Discussion

  • Mark Dickenson
    Mark Dickenson
    2006-11-09

    • status: open --> pending
     
  • Mark Dickenson
    Mark Dickenson
    2006-11-09

    Logged In: YES
    user_id=752816

    Try this...

    On line 46...

    if ($result)

    change it to

    if ($result == true)

    It shouldn't really make any difference but it is just to be on the safe side.

    I would say the problem is because you are not connecting to the database. There is no error reporting in the
    session handler if it cannot connect to the database. The adodb object is not passed to the
    $GLOBALS['ADODB_SESS_CONN'] variable. This is why it would be empty of an object.

    Create a small program that uses the exact same connection information and try to connect to the database
    containing the session table and echo the error.

    Or add...

    echo $db_object->ErrorMsg();

    at line 45 of the adodb-session.php to echo the error message that is reported from trying to connect.

     
  • Vygi
    Vygi
    2006-11-13

    • status: pending --> open
     
  • Vygi
    Vygi
    2006-11-13

    Logged In: YES
    user_id=1298799

    sorry but it does not help: initial connection to the session database is working and $db_object-
    >ErrorMsg(); is empty like expected!

    Now I have once again inserted print_r($GLOBALS) at the beginning of sess_write, right after the 95th
    line, and compared this output onder PHP 5.1 vs. PHP 5.2.

    In PHP 5.2, both pear_ADOConnection objects are completely missing: $GLOBALS['db'] (my main database
    connection $db) and $GLOBALS['ADODB_SESS_CONN'].

    Please also note that

    - sess_read() is always successful when the script starts: it successfully reads session contents, so
    $GLOBALS['ADODB_SESS_CONN'] must be still correct at this time;

    - both db and ADODB_SESS_CONN objects are also present in $GLOBALS when I put print_r($GLOBALS)
    somewhere inside of my script;

    - both db and ADODB_SESS_CONN are only missing in $GLOBALS at the very end when ADODBlite session
    management module tries to write session contents into the session database;

    - I made absolutely no changes in the script nor in the ADOdbLite; only replaced Apache's PHP module!
    under PHP 5.1 everything is always OK, under PHP 5.2 pear_ADOConnection objects are missing during
    sess_write (but still presend during sess_read and inside of my script).

     
  • Mark Dickenson
    Mark Dickenson
    2006-11-15

    Logged In: YES
    user_id=752816
    Originator: NO

    It looks there is a bug in the PHP 5 session handler. It is apparently clearing ALL objects from the $GLOBALS super global variable when it accesses the session_write of the session handler.

    Here is a fix for 5.2. Hopefully they will fix this in the next incremental update.

    Find the following lines in the adodb-session.php file

    function sess_write($sess_id, $data) {
    $filter = ADODB_Session::filter();
    $dataFieldName = ADODB_Session::dataFieldName();
    $db_object =& $GLOBALS['ADODB_SESS_CONN'];

    Add the following code right after the above lines

    if(!is_object($db_object))
    {
    ADODB_Session::sess_open('','');
    $db_object =& $GLOBALS['ADODB_SESS_CONN'];
    }

    This will recreate the database connection for the write operation of the session handler.

     
  • Mark Dickenson
    Mark Dickenson
    2006-11-15

    • milestone: --> Next_Version
    • status: open --> closed-fixed
     
  • Mark Dickenson
    Mark Dickenson
    2006-11-15

    Logged In: YES
    user_id=752816
    Originator: NO

    Damn, it isn't a bug in PHP 5. :p

    This is from the manual...

    Write and Close handlers are called after destructing objects since PHP 5.0.5. So that is just the way PHP 5 is going to work from now on.

     
  • Mark Dickenson
    Mark Dickenson
    2006-11-15

    Logged In: YES
    user_id=752816
    Originator: NO

    Here is a better way to do this that is many times faster. Ignore the previous fix for the problem.

    Find this function in adodb-sessions.php (it is at the bottom of the program)

    function _init() {
    session_module_name('user');
    session_set_save_handler(
    array('ADODB_Session', 'sess_open'),
    array('ADODB_Session', 'sess_close'),
    array('ADODB_Session', 'sess_read'),
    array('ADODB_Session', 'sess_write'),
    array('ADODB_Session', 'sess_destroy'),
    array('ADODB_Session', 'sess_gc')
    );
    }

    add one line so it looks like this...

    function _init() {
    session_module_name('user');
    session_set_save_handler(
    array('ADODB_Session', 'sess_open'),
    array('ADODB_Session', 'sess_close'),
    array('ADODB_Session', 'sess_read'),
    array('ADODB_Session', 'sess_write'),
    array('ADODB_Session', 'sess_destroy'),
    array('ADODB_Session', 'sess_gc')
    );
    register_shutdown_function('session_write_close');
    }

    This will keep the connection object so it can be used when the sess_write is called.