As others have noted, PHP's session handler is blocking. When one of your scripts calls session_start(), any other script that also calls session_start() with the same session ID will sleep until the first script closes the session.
A common workaround to this is call session_start() and session_write_close() each time you want to update the session.
The problem with this, is that each time you call session_start(), PHP prints a duplicate copy of the session cookie to the HTTP response header. Do this enough times (as you might do in a long-running script), and the response header can get so large that it causes web servers & browsers to crash or reject your response as malformed.
This error has been reported to PHP HQ, but they've marked it "Won't fix" because they say you're not supposed to open and close the session during a single script like this. https://bugs.php.net/bug.php?id=31455
As a workaround, I've written a function that uses headers_list() and header_remove() to clear out the duplicate cookies. It's interesting to note that even on requests when PHP sends duplicate session cookies, headers_list() still only lists one copy of the session cookie. Nonetheless, calling header_remove() removes all the duplicate copies.
<?php
/**
* Every time you call session_start(), PHP adds another
* identical session cookie to the response header. Do this
* enough times, and your response header becomes big enough
* to choke the web server.
*
* This method clears out the duplicate session cookies. You can
* call it after each time you've called session_start(), or call it
* just before you send your headers.
*/
function clear_duplicate_cookies() {
// If headers have already been sent, there's nothing we can do
if (headers_sent()) {
return;
}
$cookies = array();
foreach (headers_list() as $header) {
// Identify cookie headers
if (strpos($header, 'Set-Cookie:') === 0) {
$cookies[] = $header;
}
}
// Removes all cookie headers, including duplicates
header_remove('Set-Cookie');
// Restore one copy of each cookie
foreach(array_unique($cookies) as $cookie) {
header($cookie, false);
}
}
?>