I spent about 45 minutes yesterday trying to research and troubleshoot this, so hopefully someone has another idea I can try.
It started out with one of my PHP scripts detecting that the session $_SESSION was empty, so it stopped executing the rest and threw an error for me.
This entire project has worked on that server for at least half a year without any problems, and no update to code or server has been made since then.
Here's what I did then:
I created a new PHP file for testing, made sure there was nothing before or after the <?php ?> container, and wrote this code:
session_start();
var_dump($_SESSION);
$_SESSION['test'] = 5;
Then I ran the file by itself repeatedly, and it always came up with an empty session.
I had run into this before, so I checked the folder where the session files are located on the server (in my case /var/lib/php5), made sure it had the correct directory owner and permissions, deleted all the files in it and restarted apache.
No dice...
I ran the file again a few times, and each run created a NEW session file, and the session file did contain the test=5 entry, so sessions do write correctly.
So I checked the browser cookies. They are there and working as far as I can tell - both the phpsessid cookie and another cookie my site creates were there. If I delete all cookies and then run my test file again, the phpsessid cookie is recreated normally and does contain the same session id that was created as a session file.
I also added var_dump(session_id()); to the code right after session_start();, and it gave me a brand new session id every time the script ran.
We're running a PHP version that does not support session_status() yet, so that's not an option, either (not sure exactly what it would do, anyway, I'm flying rather blindly here).
So, we know sessions are created properly, the files contain the data, the cookie contains the correct id.
So as far as I can tell, the issue must lie either with the browser not sending the cookie data back to the server or the server not recognizing the session id from the cookie as an existing session.
While I was testing this, Firefox wanted to install an update, so I ran the update, but no change.
Firefox is set to receive cookies, and I did not find any exception set anywhere that would prevent them.
Given that this has been working fine for over 6 months, some freak accident must have corrupted something, but I don't know enough about Linux or the internal workings of PHP and sessions to even know where the start diagnosing.
At some point I did try session_write_close() which didn't change anything (and my whole project has always been working fine without it).
The ONLY thing that worked was this:
$c = $_COOKIE['phpsessid'];
session_name($c);
session_start();
var_dump($_SESSION);
$_SESSION['test'] = 5;
But I use session_start in a ton of pages and don't want to go through all of them to enter code that I shouldn't need in the first place...
Any thoughts?
Thanks in advance!
--- EDIT ---
I checked into the issue again, and I can confirm that the cookie name is phpsessid instead of PHPSESSID (thanks for pointing that out, #Cobra_Fast), so that is getting closer to the cause of the issue. I went into the php.ini file to put the value for session.name into quotation marks, then restarted apache, but still no change - the cookie name is still lower case. I haven't found an antivirus program on the computer, and I doubt that there's any network security that could do this... If the PHP settings are corrupted as #Cobra_Fast suggested, how could this be fixed? Editing the file just now didn't help...
After testing some more, we found a really weird thing:
Only one client computer was affected by this! We ran the code on another computer, and it worked normally, and the session cookies are written and read properly.
So it was not the server acting up at all!
I have no clue how this one computer could be just converting cookie names to lower case - it makes no sense at all, especially because it happens in two browsers...
But at least we have a "fix" for the situation, and it's out of our hands since they immediately said they were going to check that computer and re-install it if needed.
I am so majorly confused about this right now, but at least it's over :-)
Thanks for your responses!
Related
I am upgrading from PHP 7.3 to 8.1. To do this I have two separate environments; one for each level of PHP. Up until a few days ago the project was proceeding as expected. Then suddenly the PHP 8.1 environment session handling broke.
The problem that just started happening is that each time session_start() is called, a different session id is used, thus killing the previous session data. We have a custom session handler, which is identical in the two code bases.
We have been frequently updating the code in both environments to keep them pretty close together. And since this just started happening, the two code bases are very similar.
Here are some of the things I have checked:
checked the code between the two versions. There are some differences but nothing that should affect the sessions;
looked for browser output prior to the call to session_start() that has snuck in to the 8.1 code base, such as bogus characters before the <?php open tag;
checked that the session table can be written;
disabled certain functions such as error handling and ajax calls that could be affecting the issue;
checked that cookies are not blocked, which would impact session handling;
checked multiple browsers on the 8.1 environment;
compared the php.ini files in the two environments, especially with regard to session parameters.
So we have two code bases, both of which ran as expected, but now with this major difference.
Looking at the code for the session handling, the situation is that "it works over here, but not over there".
Here is the code:
//create custom session handler object
$handler = new RHSessionHandler();
session_cache_limiter('');
session_set_save_handler($handler, true);
session_set_cookie_params(3600, null, null, true, true);
session_start();
$session_id = session_id();
I might guess that there is something different between the two environments that we have not yet detected, but it would have to be something that changed in the last few working hours. There are no such changes that I know of.
EDIT
After setting this aside for a while, then coming back to it, suddenly the sessions behaved normally for about a half hour. But then after that time period, the malfunctioning started occurring again.
There were only some small code changes, which I reverted, plus a system reboot. Trying those small changes and another reboot has not removed the issue. More mystery.
EDIT 2:
Continuing to work on this I first rebooted the virtual machine and retested. Still not continuing the session but starting a new one. Then I decided to add some innocuous code for diagnostics. I added $isExistingSessionId = session_id(); right before the call to session start. Since there should be no session yet, it should be empty. But suddenly, the sessions started working again!
Not sure if this is "random" or had something to do with the jiggering the code. So I commented that new line out, and the sessions continue to work properly. Then deleted the commented line; still working properly. Not sure what to make of this.
Right now the closest thing to a pattern is the following:
Reboot the VM (effect of which might also be accomplished by just restarting apache).
Test--sessions still not working.
Wait about 5 minutes.
Sessions start working.
After a while, sessions don't work again.
EDIT 4
I have found a temporary workaround that allows me to continue to work on the upgrade to PHP 8.1, but that won't work in production.
The workaround is to set a specific session id before the call to session_start(). That way it keeps that one specific session.
As far as my immediate work, I can move forward. My hope is the cause of the problem pertains to my test environment, which is a local virtual machine that connects to a development database on another server.
The idea is that in a different environment, PHP sessions will just be working and this issue is only an artifact of my local environment. The workaround will not work in production, because each visitor has to have their own session.
Yesterday, the I'm doing some work for had their website on one server. Everything worked fine. This morning I woke up, and my password didn't work. Got the new password from IT, and started hacking away at code.
Then I start getting these oddball errors.
For example, I can login to an account, which stores an array of data in a session in php.
Here's where it get interesting.
If I had a session that was $_SESSION['attributes']['ID'], I could print it out, and get the value from it. But, when I try to evaluate against it, I'm always getting false as the return value, even when I assign it to a variable, like $x = $_SESSION['attributes']['ID'];
It's doing this across the entire system. Stuff that passed through Q/A weeks ago, and new stuff alike.
What the hell?
I've got root access, so I can fix it if it's a php.ini issue.
I just don't know where to look.
Have you ever seen this before?
Maybe the same issue I had some weeks ago: I was able to stote data into a session and I was able to read those values in the same execution of the script. But an each reload of the script, the data was missing.
The simple, yet hard to find error:
The session.save_path has become unwritable for the apache user by some odd server process one of the admins was running each night (setting the owner of the folder to root).
I simply changed the path to the upload_tmp_dir (just in case the same admin is doing the same stupid misstake again) and the session text files could be successfully stored on the hdd again.
P.S. I couldn't find it the first place as the cookie was send successfully and the initialization also worked just fine. But as PHP was unable to write the session data to the disk, all "saved" data was lost after the script died.
I've been trying to track down some annoying session issues since my webhost upgrade to PHP 5.3.3 awhile back. I've determined that if there is an active session, calling session_start() from a subdirectory kills the existing session. As an example, I start a session and a user logs in to domain.com/index.php then the user navigates to domain.com/members/ which fires start_session() ... the user's session is lost.
I've dug around for this and can't find anything similar. Is there a PHP configuration that would account for this behavior?
Calling session_start() multiple times with that version of PHP shouldn't cause any problems, however there are other possible causes.
One possible explanation is that the client's browser isn't sending the session id back to the server. You can test this out by comparing the session id that both pages produce. Assuming that you have a controlled environment where you can test this properly, you can use session_id() to get the session.
It might also be that the user is hitting a different webserver. Since (by default) PHP stores sessions to disk, there is no way for multiple servers to share the session information. If this is a shared host, it's probably quite unlikely this is the cause. You can test this out however by using phpinfo(). It should give you enough information to determine if it's the same server or not. For multi-server systems, I'd look at storing sessions in memcache or mysql.
if your sessions works all right within the same directory (it is unclear from your question), there is the only possible reason for such a behavior, a pretty obvious one: "directory" cookie parameter.
It seems it is set to somewhat unusual value, other than default "/" for the session cookie parameter.
You have to check it out.
Anyway, it is almost useless to try ANY session/cookie related problem without an HTTP interchange log.
You have to use some HTTP sniffer, like LiveHTTPHeaders Firefox addon to see what cookie header was sent by the server and which one was returned by client.
Otherwise it's all going to be shooting in the dark.
Okay, as it seems from your yonder comment, the session id remains the same, so, no HTTP issue can be a reason. The issue become a kinda tricky to spot.
Could you please post your test script here?
I've spent quite a long time searching, trying, testing for what looked like the same problem. As google kept sending me here, I think sharing the solution might help others (though I feel strange posting on a 2011 question):
Session variables set in /bar.php were not set in /foo/foobar.php.
It realised that the issue had nothing to do with folder/subfolder when I finally found out that the link in http://www.example.com/bar.php was pointing to http://example.com/foo/foobar.php (missing www).
Correcting the URL in the html link solved the problem. Having no time to dig deeper, what I can figure out is that (in my config) Apache makes no difference and serves pages indifferently with and without www, whereas PHP doesn't share the session between what it considers being two different domains, example.com and www.example.com.
Is there a PHP configuration that would account for this behavior?
Yes, if the storage for the session data differs between those calls, the $_SESSION content will differ as well. The storage can be configured, see http://php.net/manual/en/session.configuration.php for all configuration options you have with sessions.
Next to that if PHP is unable to read the session store, you will get an empty array as well.
I can't tell you if this is the issue with your problem, but probably it's helpful.
BTW, calling session_start() and than having an empty $_SESSION is commonly a sign that a new session has been created. You can verify this if you use cookies for your sessions and you output headers_listDocs:
echo '<pre>', var_dump(headers_list());
If it contains a new cookie for the session, the session has been created with this request.
Lots of good suggestions here. Thanks everyone. I spent a good chunk of the weekend digging into this and wasn't able to directly resolve it. I ended up demonstrating to my webhost that this problem happens on two of his hosted sites and doesn't happen in a default install of PHP. To work around the problem, I ended up moving all of my login and session logic into a single class.
Wanted to share another answer, found in this SO: Session variables not accessible in subdirectory answered by clayRay.
My answer was that I had a custom "php.ini" file saved in the root directory, and moving those directives into ini_set() calls solved it. You could also shove those over to .htaccess if your host allows.
Totally confused by this one...
We have a WAMPServer installation set up, running a number of virtual hosts from various document roots.
Just recently, one particular domain has started hanging the server. We traced it down to session_start(). If we comment it out, there are no problems (except, of course, for the fact that we can't do anything with the session). With it uncommented, it will hang the page load and, with enough reloads, will hang the entire server.
All of the other sites still work perfectly with their sessions. As far as I know, there is nothing different with the way sessions are being worked with. I am looking further into it (in case someone changed something) but right now I'm hoping for some direction :)
So, any thoughts?
So, I'm guessing that it's an application layer problem because the other sites' sessions are working properly. However, this assumes that they have their sessions configured the same way - save yourself some time by double checking that your site isn't doing some "unique" in its configuration compared to the other sites.
I would next examine the other session related code that is running in your application. It could be that by calling session_start() you're putting your application into a state where it will run other code. For example, maybe there's a block of code that says "only run this function if this session variable is set" and by starting the session you're exposing that variable, where it wouldn't have been exposed and therefore not run the offending function if the session wasn't started.
Good luck.
My first guess would be file permissions if you are using file based sessions. If you are using database sessions, then I would check to make sure a table isn't corrupt. Also, is it Apache, PHP or something else that's locked up?
It's possible that you hit a bug in your underlying infrastructure that you won't be able to resolve. You should at least clear all existing sessions before moving forward with trying to diagnose this.
I'm not exactly sure the question I should be asking. Sorry!
I'm working on re-doing my web site so as to be using PHP5. The server lives in a buddy's basement and I just ssh in to do my coding and view the pages just like any other page out there.
I keep track of login details in $_SESSION.
When I'm sitting at my home machine I can log into the site and everything is as I expect it in terms of the SESSION being available on all pages. When I log in on my work machine, I get a successful log in and can see the SESSION variables, but as soon as I go to another page the SESSION is gone as evidenced in session_id().
My previous web site built in PHP4 (and tweaked to keep PHP5 happy) does not exhibit this behavior allowing me to log in as expected at either location before and after the change to PHP5.
I guess I'm just looking for a clue as to what to explore next... Of all the puzzles I've encountered while teaching my self to code this one appears on the face, just crazy.
I think Jake is on to something about the cookies. Make sure your browser at work is set to accept cookies from that domain. Make sure there isn't any antivirus/antimal-ware that has disabled this. I'd use fiddler to watch the traffic and headers on your work machine, and your home machine. you should be able to quickly spot the difference since it sounds like a client issue.
It could be that the computer at work isn't supporting session cookies. It's been a while since I last read about PHP Sessions, but from what I remember...
session_start() is called.
php checks to see if the browser has sent a cookie to the server (a unique identifier needs to be supplied.
if so, it then checks checks on the server for a file with the name of the session id
if successful, it parses the file and sets the variables into the $_SESSION array
Notice that step one of this process is to actually start the session with session_start() this needs to be called before any output at all.
Have you got session_start() before output?
Do you make use of session_start() in your various php files ?
One way to get around this problem could be to store your sessions in a database.
This DevShed article by Rich Smith is a good place to start:
Storing PHP Sessions in a Database
The session is no longer saved as a file on the server, but rather an entry in the DB, and should solve any cookie issues.
Are the settings in php.ini for session.auto_start the same in both ini's?
See http://de3.php.net/manual/en/session.configuration.php#ini.session.auto-start