PHP - session_id()给我HTTP / 1.1 500内部服务器错误

PHP  -  session_id()给我HTTP / 1.1 500内部服务器错误

问题描述:

Running Apache with PHP as FastCGI.

serverinfo.php:

if (isset($_GET['session'])) {
    session_id($_GET['session']);
    session_start();
    die('You got here');
}

i won't even get to session_start() because session_id() will hang the "thread". This is the scenario:

Page [serverinfo.php] shows server info, where you can update info as well. When updating the info, a AJAX call is made to [update.php], when everything is updated [update.php] is supposed to return the same data shown in [serverinfo.php] just to "refresh" the "page" with the new data, this is done by:

update.php:

if($update) {
    $serverinfo = file_get_contents('http://127.0.0.1/serverinfo.php?session=' . session_id() . '&name=' . $_GET['name']);
    print $serverinfo;
}

The reason why i want to re-use the internal $_SESSION is because i need to access data about the client for a specific session, such as username and other important data. Otherwise serverinfo.php will just give me: "Login!" which it's supposed to do :)

I could do: include_once('serverinfo.php'); and pass the $_GET data some how but i'm not quite sure if that would work or be all that efficient :)

Accesslog from Apache:

127.0.0.1 - - [15/Feb/2012:11:03:15 +0100] "GET update.php?source=serverinfo&name=test HTTP/1.1" 500 544
127.0.0.1 - - [15/Feb/2012:11:03:15 +0100] "GET serverinfo.php?session=<session_id>&name=test HTTP/1.0" 500 544

This simply shows that update.php actually completes it's updates and tries to call serverinfo.php but it fails with Internal Server error.

apache error log:

[Wed Feb 15 11:03:55 2012] [warn] [client 127.0.0.1] mod_fcgid: read timeout from pipe
[Wed Feb 15 11:03:55 2012] [error] [client 127.0.0.1] Premature end of script headers: serverinfo.php

And here's the global error log:

[Wed Feb 15 11:04:04 2012] [warn] mod_fcgid: process 5584 graceful kill fail, sending SIGKILL

Okay, reading between the lines I think I know what's going on here.

Contrary to what you have ascertained, I think you will find it is actually session_start() that is hanging, and the cause of the 500 error is that the time limit eventually expires.

The reason session_start() is hanging is because update.php still has a lock on the session file. While you have an open session, the file is locked by the script that has it open. You can release this lock by closing the session data with session_write_close() - but this is probably not what you want to do here.

I would say that what you want to do is what you have suggested, and include 'serverinfo.php'; instead of calling it through HTTP. This will be more efficient - include does considerably less work than a HTTP request - and it will resolve the session problem. You do not need to "pass" $_GET to serverinfo.php for two reasons:

  1. $_GET is a superglobal. It is automatically available in every possible scope within the execution of a given script.
  2. When a file is included, it inherits the scope from which it was included. This means that even if $_GET weren't superglobal it would still be available in the included file, as it is available in the scope from which the file was included.

If you include the file, you also don't need to worry about making the session data available, $_SESSION has the same superglobal properties as $_GET.

All you need to do is:

update.php

if ($update) {
    include 'serverinfo.php';
}

serverinfo.php

die('You got here');
// $_GET['name'] has the same value here as it does in update.php
// Similarly, all the $_SESSION data is automatically available here