View Issue Details

IDProjectCategoryView StatusLast Update
0019936phpList 3 applicationAdmin Managementpublic21-05-19 13:23
ReporterLeftPinkie 
PriorityhighSeveritycrashReproducibilityalways
Status resolvedResolutionfixed 
Product Version3.4.1 
Target Version3.4.3Fixed in Version 
Summary0019936: PHP 7.2.0+ session_set_save_handler
DescriptionDescription...
 phpList will produce a blank screen (500 Internal Server Error in web developer network) if using PHP version 7.2.0 or higher.

Cause...
Starting with PHP version 7.2.0, setting the user-level session save handler cannot be done using the following command:
  ini_set('session.save_handler', 'user');
This is documented in PHP bug #77384 (https://bugs.php.net/bug.php?id=77384):
  Passing "user" to ini 'session.save_handler' is forbidden. Instead function set_set_save_handler() has to be called to set a user defined session handler.
The bug has been updated in the documentation's XML sources, but may take some time to propagate to the online and downloadable versions.

Resolution...
In 'admin/sessionlib.php':
if (version_compare(PHP_VERSION, '7.2', '>=')) {
    $SessionTableName = $GLOBALS['SessionTableName'];
    session_set_save_handler(
        'mysql_session_open',
        'mysql_session_close',
        'mysql_session_read',
        'mysql_session_write',
        'mysql_session_destroy',
        'mysql_session_gc'
    );
} else {
    @ini_set('session.save_handler', 'user');
    $SessionTableName = $GLOBALS['SessionTableName'];
    if (ini_get('session.save_handler') == 'user') {
        session_set_save_handler(
            'mysql_session_open',
            'mysql_session_close',
            'mysql_session_read',
            'mysql_session_write',
            'mysql_session_destroy',
            'mysql_session_gc'
        );
    } else {
        // @ini_set("session.save_handler","files");
    }
}
Steps To Reproduce1. phpList works fine using PHP 7.0 or PHP 7.1.
2. phpList will display a blank screen (with a 500 Internal Server Error) when using PHP 7.2.0 or higher.
Additional InformationPHP bug #77384 (https://bugs.php.net/bug.php?id=77384)
Tagsphp 7.2, session related, sessionlib.php

Activities

duncanc

11-05-19 06:58

updater   ~0062189

Last edited: 11-05-19 22:31

View 2 revisions

Interesting. Looking at the php documentation referenced in the php bug report it appears that the current use of ini_set() and ini_get() is unnecessary even for php versions prior to 7.2.

I can confirm that removing those statements and calling session_set_save_handler() unconditionally appears to work properly for php 5.6, with session data being stored in the phplistsessions table and the session.save_handler being set to "user" automatically.

duncanc

11-05-19 07:02

updater  

session_handler.png (50,588 bytes)
session_handler.png (50,588 bytes)

michiel

11-05-19 11:36

manager   ~0062191

Last edited: 11-05-19 11:37

View 2 revisions

Good find. We should put this on a priority list @suela

LeftPinkie

11-05-19 22:13

reporter   ~0062198

@duncanc: I can also confirm that just calling function set_set_save_handler() without setting ini config 'session.save_handler' works with PHP 7.0.

For PHP 7.2...
However, this does not work in PHP 7.2. It seems like the call back functions defined in session_set_save_handler() are not working for PHP 7.2. The session data is not being written to the database table `sessions`. If I remove session_set_save_handler(), then it works using the default ( "files"). Will need further investigation. Right now I am keeping the default session handler as files.

duncanc

11-05-19 23:48

updater   ~0062199

php version 7.2, maybe earlier versions too, is more strict about the values that the save handler functions return.

The mysql_session_read() function returns false when the session does not exist, but it should be returning an empty string. After changing the code to do that, the session handling seems to work.

LeftPinkie

12-05-19 00:35

reporter   ~0062200

@duncanc

Confirmed. This will work for PHP 5.6, 7.0, 7.2:
function mysql_session_read($SessionID)
{
    ...
// return false;
        return '';
    ...
}

As stated in the PHP doc (https://www.php.net/manual/en/function.session-set-save-handler.php)...
The read callback must always return a session encoded (serialized) string, or an empty string if there is no data to read.

Can we add this change (in function mysql_session_read() change “ return false;” to “ return '';”) to the eventual update of 'admin/sessionlib.php'?

xheni

21-05-19 09:58

administrator   ~0062231

PR: https://github.com/phpList/phplist3/pull/533