Doc #68426 [Com]: PHP >= 5.6 does not overwrite session file when session has not changed

From: Date: Sun, 16 Nov 2014 09:00:57 +0000
Subject: Doc #68426 [Com]: PHP >= 5.6 does not overwrite session file when session has not changed
References: 1  Groups: php.doc.bugs 
Request: Send a blank email to doc-bugs+get-11639@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=68426&edit=1 ID: 68426 Comment by: mark at grooveshark dot com Reported by: rpkamp at gmail dot com Summary: PHP >= 5.6 does not overwrite session file when session has not changed Status: Open Type: Documentation Problem Package: Session related Operating System: CentOS 7 PHP Version: 5.6.3 Block user comment: N Private report: N New Comment: So while this is crappy and should be addressed in later PHP versions, I think the issue you're running into will be resolved in the next minor release of PHP 5.6. I brought this up on internals and yohgaki seemed to address it afaik. See https://bugs.php.net/bug.php?id=68331 Previous Comments: ------------------------------------------------------------------------ [2014-11-15 20:22:20] rpkamp at gmail dot com Description: ------------ I'm running on a system with relatime [1] (which is the default on linux kernels >= 2.6.30 [2]). In short this means that a file's atime doesn't get updated every time that file is accessed, but only if it was also modified. The thing I found is that unlike earlier versions of PHP, PHP 5.6 does not write the session back to disk again even if nothing has changed (< 5.6 did do this, I tested this using inotifywatch). The problem with this is that when a session is running, and you don't change anything in the session for session.gc_maxlifetime, the session will be deleted, regardless of how many times it was accessed. So basically even someone browsing my website for a long time, will get their session terminated after session.gc_maxlifetime. Of course their are workarounds for this, like not using files for sessions but something else, don't mount with relatime, put a timestamp in the session on every page hit forcing the session to be flushed to disk anyway, etc, etc. My problem with this change however, is that I can't find documentation on it anywhere! The changelog for 5.6 doesn't mention it, the migration manual for 5.5 -> 5.6 doesn't mention it, and there is no info on the session manual as well. I spent about an hour and a half figuring out why my sessions were being terminated for no apparent reason. I did find that this was done as a result of bug #17860 [3] I think it's a very useful change and it should stay the way it is (not write to disk if not needed), but it really should be documented so people will know what to expect! Here is the output of stat on my session file, showing exactly what's going on PHP 5.5 ========================================================================= AFTER FIRST LOAD: File: ‘sess_om81e4ohk2r7t8nt7mplc8usm6’ Size: 14 Blocks: 8 IO Block: 4096 regular file Device: fd01h/64769d Inode: 72007296 Links: 1 Access: (0600/-rw-------) Uid: ( 48/ apache) Gid: ( 48/ apache) Access: 2014-11-15 20:15:28.491063092 +0100 Modify: 2014-11-15 20:15:28.501064363 +0100 Change: 2014-11-15 20:15:28.501064363 +0100 Birth: - AFTER REFRESH: File: ‘sess_om81e4ohk2r7t8nt7mplc8usm6’ Size: 14 Blocks: 8 IO Block: 4096 regular file Device: fd01h/64769d Inode: 72007296 Links: 1 Access: (0600/-rw-------) Uid: ( 48/ apache) Gid: ( 48/ apache) Access: 2014-11-15 20:15:57.984811596 +0100 # <-- changed! Modify: 2014-11-15 20:15:57.984811596 +0100 Change: 2014-11-15 20:15:57.984811596 +0100 Birth: - PHP 5.6 ========================================================================= AFTER FIRST LOAD: File: ‘sess_om81e4ohk2r7t8nt7mplc8usm6’ Size: 14 Blocks: 8 IO Block: 4096 regular file Device: fd01h/64769d Inode: 69810580 Links: 1 Access: (0600/-rw-------) Uid: ( 48/ apache) Gid: ( 48/ apache) Access: 2014-11-15 20:51:20.840582376 +0100 Modify: 2014-11-15 20:51:17.658177909 +0100 Change: 2014-11-15 20:51:17.658177909 +0100 Birth: - AFTER REFRESH: File: ‘sess_om81e4ohk2r7t8nt7mplc8usm6’ Size: 14 Blocks: 8 IO Block: 4096 regular file Device: fd01h/64769d Inode: 69810580 Links: 1 Access: (0600/-rw-------) Uid: ( 48/ apache) Gid: ( 48/ apache) Access: 2014-11-15 20:51:20.840582376 +0100 # <-- didn't change! Modify: 2014-11-15 20:51:17.658177909 +0100 Change: 2014-11-15 20:51:17.658177909 +0100 Birth: - I'm running this on CentOS 7.0 (Core), my uname -a is Linux pallas 3.10.0-123.9.3.el7.x86_64 #1 SMP Thu Nov 6 15:06:03 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux, and I'm running NGiNX 1.6.2 with PHP 5.6.3 and PHP-FPM 5.6.3 [1] https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Power_Management_Guide/Relatime.html [2] http://unix.stackexchange.com/questions/17844/when-was-relatime-made-the-default [3] https://bugs.php.net/bug.php?id=17860&edit=2 Test script: --------------- <?php session_start(); var_dump($_SESSION); $_SESSION['foo'] = 'bar'; sleep(ini_get('session.gc_maxlifetime') + 10); // +10 to be sure it's really over Expected result: ---------------- When reloading the page the session should still be there, i.e. the page should show array('foo' => 'bar') Actual result: -------------- The session is gone, i.e. the page just shows array() (depending on session.gc_probability and session.gc_divisor of course; to replicate this bug one should probably set session.gc_probability and session.gc_divisor to the same -positive, non-zero- value). ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=68426&edit=1

« previous php.doc.bugs (#11639) next »