A PHP web site uses cookies to store session id on the browser side. The goal is that the PHP session will be considered valid for a specific time after the most recent user interact with the site.
The PHP sessions have two distinct timeouts:
- cookie expiration - when the browser forgets the cookie containing the session id
- session expiration - when the server forgets the session data
PHP built-in logic sents the cookie only the first time the session_start()
is called, i. e. the session id is generated. The cookie is not sent on further requests and so the cookie expiration time is never extended.
In contrast to that, the PHP session expiration is extended on each request.
As a consequence, if the user interacts with the site continuously, the PHP session expiration time is being extended but the cookie expiration time keeps its original value.
Example:
- the PHP session and cookie life is set to 5 time points
- a user interacts with the site at time points 1, 2 and 4
timepoint / PHP session expiration / cookie expiration
1 / 6 / 6
2 / 7 / 6
4 / 9 / 6
- if the sure than interacts with the site at time point 7, the cookie is already expired so it will not be sent to the server. As such, the request will behave like the PHP session has expired even the PHP session is technically valid.
How to force PHP to update the cookie's expiration time on each (or almost each) request? What are the best practices?
I had not found anything useful on the web nor I find any feasible workarounds. For example, I found following suggestions:
- set the cookie to life longer initially - this just postpone the magic disappear of the cookie and does not principally contribute to the overall goal (consider the session valid after the most recent user interaction).
- regenerate the session id on each request which triggers sending a new cookie - this feels a little bit aggressive and might result in concurrency side effects (concurrent requests will probably not come from the browser serialised but in parallel)
- managing the cookies manually - this requires to mimics the logic of PHP (and keep the custom implementation compatible with the built-in logic) just to make sure a new cookie with extended expiration is sent back on each request
Note: The session in this question means a session managed by PHP, not a browser. The cookie expiration should be independent on browser sessions. As such, the suggest Is possible to keep session even after the browser is closed?
does not feel relevant at all.
Edit: The issue has been categorized as a PHP bug.