note 117157 added to function.session-start
| From: | aaronw at catalyst dot net dot nz | Date: | Thu, 23 Apr 2015 06:56:50 +0000 |
| Subject: | note 117157 added to function.session-start | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-202328@lists.php.net to get a copy of this message | ||
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);
}
}
?>
----
Server IP: 72.52.91.14
Probable Submitter: 2404:130:0:1000:c8d6:98b7:fbbe:4ea1
----
Manual Page -- http://php.net/manual/en/function.session-start.php
Edit -- https://master.php.net/note/edit/117157
Del: integrated -- https://master.php.net/note/delete/117157/integrated
Del: useless -- https://master.php.net/note/delete/117157/useless
Del: bad code -- https://master.php.net/note/delete/117157/bad+code
Del: spam -- https://master.php.net/note/delete/117157/spam
Del: non-english -- https://master.php.net/note/delete/117157/non-english
Del: in docs -- https://master.php.net/note/delete/117157/in+docs
Del: other reasons-- https://master.php.net/note/delete/117157
Reject -- https://master.php.net/note/reject/117157
Search -- https://master.php.net/manage/user-notes.php