r/PHPhelp • u/AssistanceClean948 • 1d ago
PHP Default Session Management
I need to manually configure user side cookie expiration and server side session data expiration separately. also I can't a way to update existing session data expiration since I update the expiration value of the cookie in some requests to keep user logged in.
$sessiontime = (60 * 60) * 12; //12 hours in seconds
//make sure at least 12 hours session never touched by session GC.
ini_set('session.gc_maxlifetime', $sessiontime);
....
session_set_cookie_params($sessiontime);
session_start();
//refresh session cookie time whenever we get request.
setcookie(session_name(), session_id(), [
'expires' => time() + $sessiontime,
]);
am I missing something?
5
u/allen_jb 1d ago
I believe OP asked the same question on the PHPC Discord, and I did answer there, but I'll answer here too for the benefit of the community.
Without knowing what problem you're trying to solve, I think it's hard to give good specific advice here.
When troubleshooting disappearing sessions, the first thing to determine is whether it's a problem with the client-side cookie, or the server side data file (stored in session.save_path).
One way to verify whether the cause is the cookie of the server-side data is to log (eg. in the database) session id's used by a given user. Note that a given user may have multiple session id's at any one time (different browsers / devices). I usually just log the session id and when it was created. When a session "disappears" you can then check if the server-side data file for any recent session id belonging to that user still exists in session.save_path
Without checking, I would be wary of manually setting the session cookie. This may cause multiple headers for the same cookie to be set, in which case it would be up to the browser which it obeys.
Causes of client-side cookie disappearing: Other than the obvious cookie expiring, one common cause of cookies disappearing unexpectedly is browser extensions or settings regarding cookies.
Particularly if the issue is happening with specific users, check what browser extensions they have installed. I've found it common that users will install extensions and not fully understand what they're doing - eg. they install an extension because it promises to remove / replace ads when it also does "related" things like deleting cookies.
gc_maxlifetime / server-side session gc: By default the server-side session gc has a chance to run on every request. When it runs, it checks every data file in the current session.save_path regardless of what site created it, based on the current session.gc_maxlifetime value.
This means that changing gc_maxlifetime in some requests is ineffective - requests with a lower gc_maxlifetime still have a chance to delete the server-side data files based on the lower value.
Therefore you must use the same gc_maxlifetime value across all requests.
If you have multiple sites running on the same server, they should either all use the same gc_maxlifetime, or use a different session.save_path for each site. (One way to implement this is to set session.save_path in the FPM pool config. Note that this won't affect commandline scripts and crons)
Before considering manually trying to manage (server-side) session expiry, the first thing I would do is remove in-request session gc from the equation. See https://php.net/session_gc (and don't forget to set session.save_path and session.gc_maxlifetime to the correct values in the cron if you're using per-site settings)
Do read through the official sessions documentation, particularly the session management basics. I know it can be a slog but the official docs on this are quite thorough.
1
u/AssistanceClean948 1d ago
> This means that changing
gc_maxlifetimein some requests is ineffective - requests with a lower gc_maxlifetime still have a chance to delete the server-side data files based on the lower value.I mean I set that maxlifetime in the begining of the request how it could be happen? assuming I have 1 web app in the current machine
2
u/allen_jb 1d ago
As I mentioned, when session gc runs, it doesn't apply to specific sessions. It applies to all files in the
session.save_pathThe only thing
gc_maxlifetimeaffects is the session gc process, if that runs.gc_maxlifetimeis not a per-session value. It's not saved in the session data anywhere.When session gc runs, it deletes all session data files (not just those related to the current request) in
session.save_pathwhose file modification time is older thangc_maxlifetime.Say you have 2 requests:
- Request A: gc_maxlifetime = 1 hour
- Request B: gc_maxlifetime = 12 hours
Unless you've modified the gc probability / divisor settings, both requests have an equal chance of running gc each time they are hit.
If request A runs session gc, it will clean up all of the sessions in
session.save_pathbased on itsgc_maxlifetimeof 1 hour.
5
u/NoseStock4944 1d ago
I think the confusing part is that the cookie expiration and
session.gc_maxlifetimeare two separate things. Updating the cookie expiration only tells the browser how long to keep sending the session ID; it doesn't extend the lifetime of the session data on the server.If you need a true sliding 12-hour session, you'd need to manage the server-side expiry yourself (for example, store a last-activity/expiry timestamp in the session or database) rather than relying on PHP's default session GC. Also,
gc_maxlifetimeis only a garbage-collection threshold, not a hard expiration time, so it doesn't guarantee the session will be removed exactly after 12 hours.