I encountered an issue while I was revising my session library today, and this might be the first time I've ever seen a browser-specific problem on a back end script. I hope somebody can shed some light.
Basically how the session library works is: when instantiated, it checks for a cookie called 'id' (in the form of a uniqid result) on the client machine. If a cookie is found, the script checks that and a hashed copy of the user agent string against entries in a session table. If a matching entry is found, the script resumes the session. If no cookie named 'id' is found, or if no matching entry exists in the sessions table, the script creates both. Fairly standard, I think.
Now here's the weird part: in Firefox, everything works as predicted. The user gets one session, which he'll always resume upon connection, as long as 24 hours of inactivity has not elapsed. But when I visit the page in Chrome, even though it looks the same and appears to be executing queries in the same order, I see two entries in the session table. The sessions share an agent string, but the ids are different, and timestamp logs indicate that the ghost session is being created shortly (within a second) after the one created for the user.
For debugging purposes, I've been printing queries to the screen as they're executed, and this is an example of what I'm seeing when Chrome should be opening one session and is somehow opening two instead:
// Attempting to resume a session
SELECT id FROM sessions WHERE id = '4fd24a5cd8df12.62439982' AND agent = '9bcd5c6aac911f8bcd938a9563bc4eca'
// No result, so it creates a new one
INSERT INTO sessions (id, agent, start, last) VALUES ('4fd24ef0347f26.72354606', '9bcd5c6aac911f8bcd938a9563bc4eca', '1339182832', '1339182832')
// Clear old sessions
DELETE FROM sessions WHERE last < 1339096432
And here's what I'm seeing in the database afterward:
id, agent, start, last
4fd24ef0347f26.72354606, 9bcd5c6aac911f8bcd938a9563bc4eca, 1339182832, 1339182832
4fd24ef0857f94.72251285, 9bcd5c6aac911f8bcd938a9563bc4eca, 1339182833, 1339182833
Am I missing something obvious? The only thing I can think of is that Chrome might be creating a hidden session in the background, possibly to crawl the page. If that's the case though, it could become a problem later, when I begin associating active sessions with entries in the users table. I've been looking for possible bugs in my script, but I haven't found anything so far, and everything works as expected in Firefox.
I have run into this before and was equally confused. Since a few months ago Chrome has prefetching enabled. So to speed up perceived speed to users, it crawls most links on the page and retrieves and renders them partially in advance. Great for end users since if you're on broadband it can really reduce page change times.
Unfortunately for us web developers, it leads to confusion like the above. This happens for example when a Chrome user visits a website and has not yet been assigned a cookie or session, but the browser has pre-fetched multiple pages and been assigned multiple sessions.
So let's say someone visits a page with links to different areas of your PHP script, and the script is designed to assign a cookie to all visitors...if Chrome fetches two of those pages simultaneously or close to it, PHP will end up assigning different sessions because another thread in Chrome will basically require a new session/cookie before the other assignment has been completed.
There are two solutions I'm aware of: One is Google's JavaScript API for handling prerendering, which I haven't found to be particularly good. The other way is to perform more stringent checking when handing out sessions and cookies from PHP. Either don't assign sessions to guest users, or add some additional checks (IP, hostname, whatever).
Hope that helps.