php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #68331 Session custom storage callable functions not being called
Submitted: 2014-10-31 00:43 UTC Modified: 2014-11-06 03:28 UTC
Votes:2
Avg. Score:4.5 ± 0.5
Reproduced:1 of 2 (50.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: mark at grooveshark dot com Assigned: yohgaki
Status: Closed Package: Session related
PHP Version: 5.6.2 OS: All
Private report: No CVE-ID:
 [2014-10-31 00:43 UTC] mark at grooveshark dot com
Description:
------------
Call to write are not being triggered when setting up custom handlers for sessions using session_set_save_handler if the underlying session data hasn't changed. It looks like this has been done by design for regular session handling but was calls were suppose to happen for custom session handling.

There wasn't really any documentation for this change in 5.6 but we found the commit and RFC that caused this bug.

Here is the commit that caused the bug: https://github.com/php/php-src/commit/554021d21e1b2517313a377676260c188152c2eb#diff-52eb9eb7f9d5d9125fbb1337a6541c06R549

The RFC discussing the topic is here: https://wiki.php.net/rfc/session-lock-ini
It looks like read_only and lazy_write were accepted for this RFC.

Test script:
---------------
http://gobin.io/QfTs?php

Expected result:
----------------
Session's write custom handler should be called.

Actual result:
--------------
The custom write handler is not called.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-10-31 02:36 UTC] requinix@php.net
-Status: Open +Status: Not a bug
 [2014-10-31 02:36 UTC] requinix@php.net
The state of the RFC and its code is a bit complicated. Suffice it to say that its changes are not implemented yet.

The commit you found is regarding an old request which is separate from, though did play an inspirational part in, the RFC.
  https://bugs.php.net/bug.php?id=17860
As such, the fact that the session handler (file or user or otherwise) is not called when there have not been changes to the data is intentional.

Side note: the change was mentioned for 5.6.0.
  http://php.net/ChangeLog-5.php#5.6.0
(in the Session section as "Session write short circuit")
 [2014-10-31 15:07 UTC] mark at grooveshark dot com
Sorry about linking to the RFC incorrectly; however, what is the point of having an RFC if the results are ignored by resolving a feature request bug with a finite feature from the RFC? The feature request didn't even ask for what was implemented but rather just for a flag that a session is dirty. The unfortunate part is that the RFC was created after the partial feature was implemented (which for some reason is still assigned to PHP 4.2.1 in the bug tracker).

I feel like calling this not a bug is a mistake. The documentation does not state that storage handlers won't be called in some cases. This results in custom session implementations having to do the writing in close() with a bunch of convoluted logic to get the serialized session data from read() or write(). The inability to have the timestamp updated via write() on a custom session is a bug in my opinion. This would be fine if there were something like updateTimestamp as an alternative.


Happy Halloween! Hope you have a good weekend.
 [2014-10-31 20:03 UTC] requinix@php.net
> what is the point of having an RFC if the results are ignored by resolving a
> feature request bug with a finite feature from the RFC?
The RFC is not being ignored. Might be out of the spotlight at the moment but as far as I know there's still every intention on it being implemented.
Besides, as you saw the change happened before the RFC.

> The feature request didn't even ask for what was implemented
It suggested a flag, but the core issue was that sessions were being rewritten unnecessarily and that PHP should check for changes so that the write could be skipped. @yohgaki implemented exactly that.

> which for some reason is still assigned to PHP 4.2.1 in the bug tracker
The field is for what version the bug is being filed against, not when it is fixed.

> The documentation does not state that storage handlers won't be called in
> some cases.
True, and I agree that it would be a good thing to mention.

> This results in custom session implementations having to do the writing in
> close() with a bunch of convoluted logic to get the serialized session data
> from read() or write().
If you want to make write() rewrite the session regardless of changes, apparently? The point is that you don't have to do that.
The RFC reintroduces the idea of lazy writing as an optional feature so when that is in then you'll be able to (not) use it.

> The inability to have the timestamp updated via write() on a custom session
> is a bug in my opinion. This would be fine if there were something like
> updateTimestamp as an alternative.
Personally I prefer this lazy writing. write() can update a modification timestamp, open() or close() can update an access timestamp, and you GC based on access time.
With that said, the RFC (well, the code in its PR) does introduce a supplemental interface "SessionUpdateTimestampHandler" which adds a method "updateTimestamp" that would be called during lazy writing instead of write(). So that should address your concerns.

Putting aside your (very understandable) confusion regarding the lazy writing change and the RFC, I NABed this because the change was made intentionally as a resolution to an old feature request. Now that you've explained that it's not just a matter of an unexpected change but that it causes a problem for you, though it still seems an avoidable one to me, I'd reconsider.

However the RFC still resolves that. I'm not entirely sure of its status, but like I said I think it's still intended to be merged in at some point. There might have been an outstanding issue preventing it from being merged into 5.6? If you're not averse to mailing lists then I suggest asking on internals to find out for sure what's happened to it.
  http://php.net/mailing-lists.php
 [2014-11-01 00:57 UTC] jay at grooveshark dot com
Fellow Grooveshark developer here. Our session handler adds some OOP functionality, the reasons for which are outside the scope of this discussion, but the reason this change causes problems for us is that PHP does not always know when the session data has changed, because some of our session data is not part of $_SESSION. Our custom save handler already checks to see if a write is actually necessary, so this optimization not only causes this bug for us where write is not being called when we expect it to be, but it also doesn't optimize anything for us. If this functionality was behind a flag we could easily turn it off, but for now we are having to choose between rewriting the way our session handler works or recompiling PHP without the code in that commit.
 [2014-11-01 01:31 UTC] requinix@php.net
Then you should definitely raise the issue on the internals list. I've read through a lot of emails about this but I'm still not certain why the RFC's code is pending - they might be able to resolve it, or at least explain what its current state is.
 [2014-11-04 14:55 UTC] denis at slik dot eu
This is a backwards incompatible change.
For reasons very similar to the original submitter, this has broken our application.

Strongly consider updating your migration notes as well as the original documentation:
http://php.net/manual/en/migration56.incompatible.php
http://lt1.php.net/manual/en/function.session-set-save-handler.php
 [2014-11-04 22:35 UTC] james at grooveshark dot com
> The RFC reintroduces the idea of lazy writing as an optional feature   > so when that is in then you'll be able to (not) use it.
That's not a problem. Its fine for it to be optional but in 5.6 its NOT optional and there's no way to turn off lazy writing. The RFC said there would be, but there's not.

> With that said, the RFC (well, the code in its PR) does introduce a    > supplemental interface "SessionUpdateTimestampHandler" which adds a    > method "updateTimestamp" that would be called during lazy writing     > instead of write(). 
That's also fine, but was not implemented. As the RFC was implemented, there is no way to turn off the lazy write functionality.

If there was ANY way to turn off this functionality (besides rebuilding PHP without the mentioned comment, which is what GS is doing now), then this wouldn't be an issue at all. Because of that, I'd consider this to be a bug. The RFC was fine in that it introduced multiple workarounds but that was not implemented, which is why it is breaking applications.
 [2014-11-05 21:20 UTC] yohgaki@php.net
-Status: Not a bug +Status: Re-Opened -Type: Bug +Type: Feature/Change Request
 [2014-11-05 21:20 UTC] yohgaki@php.net
I don't understand the reason why you need "write" even when session data was not changed at all.

BTW, I was suggesting "update" handler for the RFC introduce this feature, but there were objection and withdrawned.

I may try to add user space "update" again.
 [2014-11-05 21:39 UTC] mark at grooveshark dot com
> I don't understand the reason why you need "write" even when session data was not changed at all.

Two reasons I brought up on the internals thread:
- We would like to update the timestamp of the session.
- We have some data that isn't in $_SESSION that needs to be written. We don't use $_SESSION because we need the data to be indexable (not serialized) and didn't want to duplicate the data in two places.

> BTW, I was suggesting "update" handler for the RFC introduce this feature, but there were objection and withdrawned.

I'm unaware of the full objection to that idea; however, I think calling the write() custom handlers until an alternative is implemented would suffice to fix this issue. I understand that doing the lazy write call was an optimization for normal sessions but this change can break some custom session implementations.

> I may try to add user space "update" again.

Based on what was said on the internals thread it sounds like this isn't an option for PHP 5.6. I assume you mean something can be done for 5.7 and for PHP 5.6 the commit will just have to be reverted?
 [2014-11-05 22:25 UTC] yohgaki@php.net
-Type: Feature/Change Request +Type: Bug -Assigned To: +Assigned To: yohgaki
 [2014-11-05 22:25 UTC] yohgaki@php.net
Since your are using user save handler, I think this could be fixed as a bug. I have to check the code to be sure, though.
 [2014-11-06 03:11 UTC] yohgaki@php.net
-Status: Re-Opened +Status: Feedback
 [2014-11-06 03:11 UTC] yohgaki@php.net
Hmm. The commit you're referring is nothing to do with you issue. It was reverted and new PR is there for this. (It seems should be adjusted and committed)

https://github.com/yohgaki/php-src/compare/PHP-5.6-rfc-session-lock

It isn't merged yet. So lazy write patch is unrelated at all.

I've tried see if issue could be reproduced, but it cannot.
Could you write full/working reproducible script?
 [2014-11-06 03:28 UTC] yohgaki@php.net
-Status: Feedback +Status: Open
 [2014-11-06 03:28 UTC] yohgaki@php.net
I found what's wrong. Since lazy write patch was in discussion and I left WIP patch in the repo and left this patch merge to RM. This must be addressed ASAP.
 [2014-11-06 04:55 UTC] yohgaki@php.net
Automatic comment on behalf of yohgaki
Revision: http://git.php.net/?p=php-src.git;a=commit;h=4dd3fbfcd28f8a3826361c5c4b7aa4c4da592b22
Log: Fixed bug #68331 - This was partial patch for https://wiki.php.net/rfc/session-lock-ini
 [2014-11-06 04:55 UTC] yohgaki@php.net
-Status: Assigned +Status: Closed
 [2014-11-06 04:55 UTC] yohgaki@php.net
Automatic comment on behalf of yohgaki
Revision: http://git.php.net/?p=php-src.git;a=commit;h=4dd3fbfcd28f8a3826361c5c4b7aa4c4da592b22
Log: Fixed bug #68331 - This was partial patch for https://wiki.php.net/rfc/session-lock-ini
 [2014-11-18 20:34 UTC] ab@php.net
Automatic comment on behalf of yohgaki
Revision: http://git.php.net/?p=php-src.git;a=commit;h=4dd3fbfcd28f8a3826361c5c4b7aa4c4da592b22
Log: Fixed bug #68331 - This was partial patch for https://wiki.php.net/rfc/session-lock-ini
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Fri Jun 23 22:01:40 2017 UTC