Recently my webhost changed the PHP configuration. The only complaint I have is that sessions expire while in use.
Generally, I just write once to the session, but read many times, so I thought this may be because the filemtime wasn't changing, so every time I read, I also write by incrementing a counter. Still nothing, after 24 minutes, whether the session is being used or not, it gets cleared.
Any ideas on how to fix this?
PHP constantly reads and writes the session data file when you start a session and end the script (or call session_write_close()), so the file mtime should change. There is no need to change the atime option of the filesystem.
But things can easily go wrong beyond that, including having strange cronjob scripts running that delete session files. Without you complaining at the service desk, they will never fix it.
Related
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?
For some odd reason, just today our server decided to be very slow during the starting of sessions. For every session_start, the server either times out after 30 seconds, or it'll take about 20 seconds for it to start the session. This is very weird, seeing as it hasn't done this for a very long time (the last time our server did this was about 7 months ago). I've tried to change the session to run through a database instead, and that works fine, however, as our current website is built, it'd take days to go on every page and change the loading of sessions to include a new session handler. Therefore my question remains:
Why is it so slow, and why only sometimes?
We run on a dedicated hetzner server with 24GB's of ram, and a CPU fast enough to just run a simple webserver (a Xeon, I believe, but I'm not sure). We run debian on the server with an apache+fastcgi+php5 setup.
The server doesn't report much load, neither through server-status as well as the top command. Vnstat reports no problem whatsoever with our network link (again, that wouldn't result in a slow local session handling). IOtop reports no problem with processes taking over the entire harddrive. Writing to the tmp folder where the session files are located works fast if done through vim.
Again, to make this clear, my main concern here isn't whether or not we should switch to a DB or a memory-cached version of the sessions, it's simply to ask why this happens, because everything I take a look at seems to be working fine, except for the PHP itself.
EDIT:
The maximum file in our PHP tmp directory is 2.9 MB, so nothing that should make an impact, I believe.
UPDATE: I did never figure out what was wrong and/or how to fix it, but the problem disappeared after we switched over to memcached/db sessions.
Have you tried session_write_close(); ?
This will disable write-ability in session variables but you can still read data from them. And later when you need to write a session variable, reopen it.
I have also suffered from this problem but this thing worked like a charm. This is what i do:
session_start(); //starts the session
$_SESSION['user']="Me";
session_write_close(); // close write capability
echo $_SESSION['user']; // you can still access it
I had the same problem: suddenly the server took 30 seconds to execute a request. I noticed it was because of session_start(). The first request was fast, but each next request took some 30 sec to be executed.
I found that the session file in c:\wamp\tmp was locked by the first request for some 30 sec. During this time the second request was waiting for the file to be unlocked.
I found out it had something to do with rewrite_mod and .htaccess. I disabled rewrite_mod and commented out every line in .htaccess and it works again like a charm. I don't know why this happend because I don't remember change any settings or conf on wamp.
I ran into this problem too. It was answered here:
Problem with function session_start() (works slowly)
Sessions are locked by PHP while one script is executing, so if scripts are stacked under the same session, they can cause these surprisingly long delays.
Each session is stored by apache as a text file.
When session start is use to resume an existing session (via cookie identifier for example) maybe a big session file (a Session with a lot of content inside) can be slow to be started?
If this is the case probably you application is putting to much data into sessions.
Please check if you have correct memcache settings e.g. in /etc/php.d/memcached.ini
I know this is an old question but I've just fixed this issue on my server. All I did was turn on the bypass cache for the domains in the cache manager in the cpanel.
My sessions were taking ages to start and close now they are instant.
Sessions also may start slow if you put many data in it. For example 50MB of data in session in docker image may result in 3 seconds of session start time.
I would like a function to run whenever a session is destroyed. I've looked into using session_set_save_handler but I don't want to manually handle the storage of sessions, I just want to do a little processing when they're destroyed. Is there any way to do this without using session_set_save_handler?
The handler is pretty much the only method I think. A session can also be destroyed as part of the garbage collection and both of those can only be intercepted by using the session_set_save_handler that I know of.
The only way as I see it is to turn of garbage handling, and do that yourself. Wouldn't work for memcached based sessions, but file-sessions are easily traceable / loadable / removable (just look for files not recently accessed in the session directory).
If you're not managing sessions manually, then they're most likely stored as files, and like Wrikken said, you could delete older session files yourself with a cron job.
But really, that's the job of the garbage collector. And the whole session_set_save_handler isn't that hard to use. You can install a ready-made, and just trigger your function when the garbage collector is invoked.
You can do it with register_shutdown_function(). The function is executed when the script exits.
Edit: Since my answer above was seen to be incorrect, I'm editing to give a better answer. You can call whatever function you like before or after you call session_destroy(). Session is erased only when you call session_destroy() explicitly. Note that PHP also cleans expired sessions in a cron job, if one is set up by the system administrator, but you have no way of affecting that cleanup from a php script.
This is something that's easily done in other languages that have a full application platform like Java, .NET, etc. For example you have events that are fired by the server at startup, application startup, session end, etc. With PHP there is no real concept of an "application" in the same sense as the other languages, so you don't have those events that are fired by the app server. But there are things you can do manually.
Probably the easiest thing to do is to simply timestamp a DB record for each user that is logged in on every page load. Then you have a cron job running to look for timestamps that have expired (meaning the user hasn't loaded another page within 20 minutes - or whatever your timeout is). You can then do whatever action is necessary. a nice bonus of this is that you can write something to monitor which users are logged into your system at any given moment.
Another idea is that you could actually write something on the server to look through the PHP folder that contains the session files. However matching these up with users would probably be difficult.
I'm trying to use ajax to make multiple simultaneous requests to a php script, however, it only seems to do 1 instance at a time and I cannot connect to do the next call until the previous one is finished. What do I have to do in order to make it do them all at the same time? I'm using apache (xampp) on windows. I've also tested this on my unix server and the same thing is happening there as well.
In theory, there is nothing preventing one PHP script from being executed several times in parallel -- else, a lot of websites would have big problems ;-)
So, there is probably, in your situation, some locking mecanism that prevents this...
If your script is using sessions, and those are file-based (which is the default), those sessions could cause that kind of problem : with the default session handler, it's not possible to have several files accessing the same session data (i.e. the session data that corresponds to a given user) at the same time ; that's to prevent one script from overriding the data of another, and should probably not be disabled.
So, if your script is using sessions : would it be OK for you to stop using sessions ?
If not, you should try to close them as soon as you don't need them -- to unlock the files that are used to store them.
Here's a quote from the manual page of session_write_close, about that :
Session data is usually stored after
your script terminated without the
need to call session_write_close(),
but as session data is locked to
prevent concurrent writes only one
script may operate on a session at any
time. When using framesets
together with sessions you will
experience the frames loading one by
one due to this locking. You can
reduce the time needed to load all the
frames by ending the session as soon
as all changes to session variables
are done.
I have programmed a simple app that every X minutes checks if an image has changed in several websites and downloads it. It's very simple: downloads image header, make some CRC checks, downloads the file, stores in a MySQL database some data about each image and process next item...
This process takes about 1 minute to complete.
The problem is I have noticed that while the server is executing this process I cannot access to any page in the website, even those that don't require MySQL.
I don't know why it is happening and I have no clue about how to fix it. Perhaps a more advanced PHP programmer can help me.
I think this is because of session files locks
Try to unset sessions cookie and load page, if I right - page is loaded
It would be correct to remove execute this script from web, but if this is necessary, use session_write_close() function to close session and unlock session file