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
Related
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.
For the adminpanel of our CMS, it turns out some customers like to have a lot longer than aproximately 30 minutes to save data in the administration panel. They get distracted or get a phonecall... and then instead of the data being saved as they expect, they have to log in again and lose changes.
I have tried to keep the session alive with an ajax call Javascript does not call file
That first seemed to work, but eventually does not have the desired effect. If I leave the browser alone, the session dies after 1-2 hours. (I save a timestamp to a textfile every 5 minutes, so I can see exactly when the session stopped being alive).
I have been reading a lot about this issue, apparently the garbage collector kills off sessions anyway, if they are around longer than the session.gc_maxlifetime set in php.ini
My consideration is now, to set the session.gc_maxlifetime in the php.ini much higher and then set the session.gc_maxlifetime lower in a php config file for the clients who do not need this. Also for the frontend I don't want the session to be alive for hours. This way I turn it around and controll the sessions that are not supposed to last longer then default.
Would this be good practice? Will this create undesired effects?
Any advice on the path to take or possible other solutions?
My project is in zend framework and I want to increase the user inactivity time to 1-2 weeks. Cookies for my browser setting correctly but the session logs out user after 8 hour as I have set the session.gc_maxlifetime value to 28800. So I just wanted to confirm before moving forward that "Would it increase the server load, if I increase PHP session.gc_maxlifetime to 1-2 week?"
By default, session data is stored as serialized object in plain text files on the hard disk of your server. Higher session timeout then means more session files in the folder. You won't experience any significant increase in server load, but depending on the amount of sessions you might hit filesystem limitations (scan time increases with the amount of files in a folder)
Alternative session storage like MySQL might be a solution
Sessions are maintained on server for each user. Increase in session time out will prevent the Server from releasing memory allocated to inactive session.
So yes, if you have too many users and you keeping their session for week, then you will performance issue.
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).
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.