php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #75628 session_set_save_handler() prints warnings in a unit test
Submitted: 2017-12-05 08:38 UTC Modified: 2018-10-04 07:46 UTC
Votes:15
Avg. Score:4.3 ± 0.9
Reproduced:14 of 14 (100.0%)
Same Version:10 (71.4%)
Same OS:3 (21.4%)
From: damyon at moodle dot com Assigned: yohgaki (profile)
Status: Not a bug Package: Session related
PHP Version: 7.2.0 OS: Linux Mint 17.3 Rosa
Private report: No CVE-ID: None
 [2017-12-05 08:38 UTC] damyon at moodle dot com
Description:
------------
When unit testing session-related code in a CLI environment, appropriate PHP ini settings combined with passing false to session_cache_limiter should allow the session handler to be changed even if output has been already sent.

With PHP 7.2.0RC5 calling session_set_save_handler prints warning messages, regardless of php ini settings.

Very similar previously fixed bug:

https://bugs.php.net/bug.php?id=55267

Very similar (but not the same) bugs with php 7.2

https://bugs.php.net/bug.php?id=74936
https://bugs.php.net/bug.php?id=74514

Test script:
---------------
<?php                                                                                                                               
S>                                                                                                                                    
  ini_set('session.use_cookies', false);                                                                                              
  ini_set('session.use_only_cookies', false);                                                                                         
  ini_set('session.use_trans_id', 1);                                                                                                 
  ini_set('session.cache_limiter', false);                                                                                            
  session_cache_limiter(false);                                                                                                       
                                                                                                                                      
  echo '.';                                                                                                                           
                                                                                                                                      
  class MySessionHandler extends SessionHandler                                                                                       
  {                                                                                                                                   
S>                                                                                                                                    
  }                                                                                                                                   
                                                                                                                                      
  $handler = new MySessionHandler();                                                                                                  
  session_set_save_handler($handler, true);

Expected result:
----------------
One single dot of output

Actual result:
--------------
.PHP Warning:  session_set_save_handler(): Cannot change save handler when headers already sent in [filepath]/test.php on line 17


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-12-05 08:48 UTC] damyon at moodle dot com
Sorry the test script has "S>" lines in it (copy / paste problem).
 [2018-01-23 09:27 UTC] matteo dot scaramuccia at gmail dot com
Hello,
is there any dev progress here?
Still relevant in 7.2.1 too.

TIA,
Matteo
 [2018-05-31 15:12 UTC] jeroen at asystance dot nl
Confirmed in version 7.2.5.
 [2018-07-27 11:37 UTC] jeroen at asystance dot nl
I've written a php test case (phpt) for this bug. It fails on a fresh build of 7.2.8 (./configure without any flags).

--TEST--
Bug #75628 (session_set_save_handler() prints warnings in a unit test)
--SKIPIF--
<?php if (!extension_loaded("session")) die("skip session extension not available"); ?>
<?php unlink(__DIR__. '/sess_' .session_id()); ?>
--INI--
session.use_cookies=0
session.cache_limiter=''
--FILE--
<?php
    class MySessionHandler extends SessionHandler {}
    echo ".\n";
    $success = session_set_save_handler(new MySessionHandler(), true);
    echo ($success ? 'set' : 'fail') . "\n";
--EXPECT--
.
set


This bug is clearly a regression in 7.2 and prevents users from running (PHPUnit) tests against code that sets session handlers.
 [2018-09-28 15:31 UTC] jeroen at asystance dot nl
7.2.0alpha1 already has this regression.

I'm trying to pinpoint the commit that causes this bug but it's a slow process.
 [2018-10-01 13:39 UTC] jeroen at asystance dot nl
7.1.22 are fine, and 7.3.0RC2 fails.
 [2018-10-02 10:27 UTC] yohgaki@php.net
-Assigned To: +Assigned To: yohgaki
 [2018-10-02 10:35 UTC] yohgaki@php.net
-Status: Assigned +Status: Not a bug
 [2018-10-02 10:35 UTC] yohgaki@php.net
You cannot change anything for session, once you have started output.

    echo ".\n";
    $success = session_set_save_handler(new MySessionHandler(), true);
    echo ($success ? 'set' : 'fail') . "\n";

echo should print 'fail', but it's not. This must be bug. I'll look into this.

If you want to start output before session initialization, use ob_start() prevent PHP from start sending output.
 [2018-10-02 10:42 UTC] yohgaki@php.net
Checked session_set_save_handler() returns FALSE for invalid usage. i.e. Returning FALSE for code won't work correctly. There is not bug. Please read UPGRADING in PHP 7.2.
 [2018-10-04 07:46 UTC] yohgaki@php.net
The reasons why CLI command line mode respects HTTP headers/output:

1) Session manager has 2 modes "cookie" and "transid". Both of them cannot work once output is started. i.e. Cookie requires to write HTTP header for session id cookie. Transid requires to rewrite output to embed session id in it.

Note: Older PHP was too tolerant for invalid usages. It allowed codes that can never work under web environment without errors. Even when it might seem to work, it didn't. PHP 7.2 session raises errors for codes that cannot work. i.e. Users can easily identify critical session management code bugs.

2) CLI has built-in web server mode. If CLI command mode behaves differently, it is very confusing. The same code work for one, but not for other.

3) CLI is used for testing. If CLI command line mode works differently, test code can be bogus that cannot work with web SAPIs including CLI's built-in web server.


Technically, session module can ignore header/output. However, allowing session management code that cannot work under web environment has more harm than good.

For those who have issues with stricter checks, please use ob_start(). Then your code works for all PHP versions since PHP 4.

With PHPUnit, you may want to redirect errors to stderr.
 
PHP Copyright © 2001-2018 The PHP Group
All rights reserved.
Last updated: Sun Oct 21 12:01:26 2018 UTC