What exactly happened?
I don't know the undergoing so I can't understand how session_set_save_handler() actually works.
Session timeout is declared in php.ini
If you can edit the php.ini, change:
session.gc_maxlifetime 72000
If you cannot edit the php.ini, put this in your .htaccess file:
php_value session.gc_maxlifetime 72000
That should allow the session to "live" for at least 20 hours (72,000 seconds), even without any activity.
If that doesn't work, and you're on a shared host, it could be that the host empties the session directory on a periodic basis. Do your sessions all die after a pre-determined amount of time? (i.e. 10 mins?) If that's the case, you could move your sessions into the database using a custom session handler.
Most people would think session.gc_maxlifetime defines the session’s lifetime.
But that’s not quite correct. session.gc_maxlifetime is only the lifetime after that the garbage collector of PHP’s session implementation assumes the session to be expired. But the garbage collector is only called with a chance of 1% (default settings). So it’s very probable that the session might be used though it is already expired.
The best would be if you implement a session timeout mechanism on your own and register it with session_set_save_handler. It should test if the current session is still valid and invalidate it immediately if it’s expired.
See my response to How do I expire a PHP session after 30 minutes? for further details.
Related
I've observed that my PHP pages in the production environment session times out but unable to figure out what determines the duration of time out.
I use AWS ElasticBeanstalk to run the PHP code.
I'd like to find out
what is the session time set to and where is it set typically?
how I can programmatically control the time out from the PHP layer
Thanks in advance
If the session timeout is not explicitly set through the code, then you can check the default value set in the php.ini file for session.gc_maxlifetime which specifies the number of seconds after which data will be seen as 'garbage' and potentially cleaned up. Garbage collection may occur during session start (depending on session.gc_probability and session.gc_divisor). Defaults to 1440 (24 minutes).
References:-
session.gc_maxlifetime
PHP - How to implement session lifetimes
The PHP session data is stored on the server side in sess_{$hash} files in the directory defined in the session.save_path setting of php.ini.
If my understanding is correct, these files should get removed after a defined period of time. How to get and how to set this time? I tried settings session.cache_expire and session.gc_maxlifetime. E.g. I set session.cache_expire to 2 (minutes), but after two minutes the files are still there. I also set session.gc_maxlifetime to 120 (seconds). But this also didn't work.
How to configure PHP to get the sess_* files being removed after a defined period of time?
The session.gc_maxlifetime is what defines when sessions data is marked for garbage collection (not necessarily when it's deleted). The actual deletion of that data depends on a number of variables. Most prominently the session.gc_probability and session.gc_divisor. The probability over the divisor determine the chance that the session initialization process will invoke the garbage collector to clean up marked garbage. By default they are 1 and 100, respectively (meaning there is a 1% chance the garbage collector will clean up).
This is PHP's default mechanism for garabage collection of session data. However, on some systems (most notably Ubuntu) the default session GC is replaced by an external cleanup mechanism which is implemented as a cron job that runs regularly to clean up session files based on stat calls and the session.gc_maxlifetime.
You tend not to notice these side effects on a busy site, as the number of session_start() calls increase, the probability that stale session data is regularly cleaned up increases. However, on a low traffic site (namely your development environment) this probability drops significantly enough that you might notice stale session data hanging around for a while. This is typically not something to be concerned with. As long as you are deleting the session cookie and regularly using session_destroy() when the session needs to be deleted, this is all moot.
The Problem:
I have a website that uses PHP sessions to allow users to log in. It works fine. But the session expires too soon that 1 minute of inactivity will log out the user.
My Environment:
Php version: 7.1
Server: NGINX
Framework: CakePHP 3.5
What I did so far?
I did every single solution on the StackOverflow or any search result I get. I extended my session timeout both in php.ini and CakePHP configurations.
The solution
After 2 or 3 days of research, I found the solution. In my php.ini I found a configuration named session.gc_probability and I put value 0 for that. Now my sessions never get expired except if the user logs out intentionally.
And now my current problem is, I don't want my session.gc_probability configuration to be zero as it will not collect any garbage (Not really sure about this. Please correct me if this information is wrong.). And this will cause the sessions to remain for month or years which a real GARBAGE for the server.
I got the idea of giving session.gc_probability zero value from here
session.gc_divisor coupled with session.gc_probability defines the
probability that the gc (garbage collection) process is started on
every session initialization. The probability is calculated by using
gc_probability/gc_divisor, e.g. 1/100 means there is a 1% chance that
the GC process starts on each request. session.gc_divisor defaults to
100.
What is exactly wrong with my configurations? What causes the garbage collection to remove my sessions that soon? session.gc_probability was 1 and session.gc_divisor was 1000. I think a process with 1/1000 probability should not start every 1 or 2 minutes.
According to your follow-up comments your setting for Session.handler is php. The Sessions documentation explains:
The built-in configurations are:
php - Saves sessions with the standard settings in your php.ini file.
cake - Saves sessions as files inside tmp/sessions. This is a good option when on hosts that don’t allow you to write outside your
own home dir.
[…]
The default php.ini setting for session.save_path depends on your PHP distribution (and it can be changed anyway) but it normally involves a shared data storage for all PHP applications that do not opt out. That means that the app with the shortest session.gc_maxlifetime is likely to remove session data from other apps.
Switching to cake should address that.
A little follow-up about session.gc_probability and session.gc_divisor. Setting them too aggressively will cause frequent garbage collection. That may harm performance but it won't cause premature data expiration. On the other side, too loose values will still allow access to obsolete data.
I have set the maxlifetime for sessions to be 0 in php.ini, so; as I understand it will be available until I close the browser.
But it doesn't, as when I leave the browser idle for sometime, and I get back to work on the app, I get to login page, which means that the session is destroyed !!
Any suggestions ?!
There is another lifetime setting which specifies after which time the server may remove the session to avoid to many stale sessions hogging the server's resources.
Quoting from the manual:
session.gc_maxlifetime specifies the number of seconds after which data will be seen as 'garbage' and potentially cleaned up. Garbage collection may occur during session start (depending on session.gc_probability and session.gc_divisor).
I have an upload form that takes a user about 30 min. to complete. The whole time they're idle on this page. I use the ini_set() function. You can see the top of the upload page here:
<?php
session_start();
ini_set('session.gc_maxlifetime',10080);
?>
What keeps happening is if a user is idle for 30 or more min. the data gets truncated and the User_id is recorded as a NULL value. I'm completely baffled how this is happening. I initially set the maxlifetime in the php.ini but that overloaded the cached session data. So, I'm just using ini_set. Why would the data be getting messed up and the user_id not be getting recorded. Note: if you do the form fast enough there's no issues.
You should use ini_set() before the session_start().
That's because there are another scripts called with session.gc_maxlifetime value ~30 minutes. So other scripts' session garbage collector clears the out of time sessions (from their perspective the sessions are timed out).
The solution: you need to change the global value of session.gc_maxlifetime in php.ini or .htaccess or specify the same (or at least larger) value in every script.
Setting session.gc_maxlifetime with ini_set does not necessarily have effect on the way the server purges the sessions.
For instance, on Debian (and, i imagine on some other systems as well), the sessions are being purged by a cron job that is not affected by any configuration you do inside the script (it only reads global php.ini settings).
You can increase this server-wide in php.ini if that is the case.
You can override session save handler and then deal with session expiration yourself...
you can use some ajax keepalive calls so that even when the user is idle on that form page there is something "talking" to the server within the expiration timeframe to keep the session alive