Doc #68426 [Com]: PHP >= 5.6 does not overwrite session file when session has not changed
| From: | mark at grooveshark dot com | 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