header()如何工作?

时间:2011-11-10 15:32:56

标签: php

一点背景:
我需要在浏览器中运行PHP脚本,但我不想在安装服务器时遇到麻烦,并且要承受在我的计算机上运行服务器的所有开销以及随之而来的所有东西,包括防火墙,等等等等等等。

所以我编写了自己的服务器。这是一个简单的PHP脚本,它侦听我的局域网IP的端口80上的连接,然后我只是在我的浏览器中加载该IP并且它可以工作。它接收HTTP请求并使用exec启动第二个PHP脚本 - 这样我就可以轻松地对其进行更改而无需重新启动服务器脚本。第二个PHP脚本解析请求,最后include实际调用的脚本。它从那里获取输出,并使用适当的标题(我可以更改)将响应发送回浏览器。

是的,这是一团糟,但它确实有效。它做我需要它做的事。

现在提出问题:
我无法使用header()。它似乎对通过套接字连接发送回浏览器的内容没有任何影响。我改为制作了一个setheader()函数,并将标题存储在一个数组中以作为响应的前缀。

我想知道header()函数在内部是如何实际工作的,这样我就可以使用该函数而不是我的“黑客”函数。

7 个答案:

答案 0 :(得分:2)

CLI SAPI完全忽略了header()功能。它虽然对Apache和CGI SAPI有影响。

简单地说,CLI SAPI没有在sapi_*_header_*函数中实现任何逻辑。例如,对于CLI SAPI,在php_cli.c

static int sapi_cli_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC) /* {{{ */
{
    /* We do nothing here, this function is needed to prevent that the fallback
    * header handling is called. */
    return SAPI_HEADER_SENT_SUCCESSFULLY;
}
/* }}} */

所有这些功能基本上都会返回NULL0或假成功消息。

对于CGI SAPI,在cgi_main.c

static int sapi_cgi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
{
    char buf[SAPI_CGI_MAX_HEADER_LENGTH];
    sapi_header_struct *h;
    zend_llist_position pos;
    zend_bool ignore_status = 0;
    int response_status = SG(sapi_headers).http_response_code;

    // Lots of other code...
}

您可以使用php-cgi二进制文件和一些数组操作轻松完成此工作:

<强> server.php

$script_to_run = 'script.php';
exec('php-cgi '.escapeshellarg($script_to_run), $output);
$separator = array_search("", $output);

$headers = array_slice($output, 0, $separator);
$body = implode("\r\n", array_slice($output, $separator+1));

print_r($headers);
print $body;

<强>的script.php

header('Content-Type: text/plain');
echo 'Hello, World!';

输出:

Array
(
    [0] => X-Powered-By: PHP/5.3.8
    [1] => Content-Type: text/plain
)
Hello, World!

答案 1 :(得分:1)

header()函数与您的实现完全一样:它只是在页面内容之前在响应中发送纯文本标题(如果任何内容已经发送到客户端,这就是它会抛出错误的原因) 。所以,我认为你正在以正确的方式做到这一点。无论如何,您的实施中存在一些问题。我认为安装Web服务器会容易得多。

答案 2 :(得分:0)

你使用正确的CGI式呼叫吗? - 否则大多数HTTP相关的函数将无法在PHP中运行 - 并且CGI不如Apache或IIS的库调用那样最好

为什么不采取EasyPHP或类似的东西?

PS“解析请求”是什么意思?

答案 3 :(得分:0)

实际的发送标头由PHP的SAPI(服务器API)层执行。示例SAPI包括Apache的mod_php和PHP的CLI版本,它们将在您调用exec时运行。对于CLI SAPI,发送标头是noop,因为通过命令行运行脚本显示HTTP标头通常没有意义。

尝试使用php-cgi作为二进制而不是PHP。 CGI SAPI应输出正确的标题。

答案 4 :(得分:0)

由SAPI模块(调用PHP脚本的代码)决定如何处理标头。您可能正在使用的CLI SAPI忽略了脚本设置的任何标头。可以与php-cgi命令一起使用的CGI SAPI默认输出它们,但支持命令行界面来抑制它们。理想情况下,您只需编写自己的SAPI模块,即可与Web服务器正确连接。

答案 5 :(得分:0)

通常的HTTP响应如下:

HTTP/1.1 200 OK
Date: Thu, 10 Nov 2011 15:35:27 GMT
Server: Apache
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=None

<!DOCTYPE html>
<html>
....

PHP函数header()负责将 - 井, - 标题放入响应的第一部分。您可以使用print等输出的实际HTML。

现在,如果它是一个PHP脚本,玩Apache,这个脚本负责将标题行放在其响应中。 header()仅在输出发送到stdout而不是自定义写入套接字时才有效,这样,在PHP-CGI脚本结束后,可以在输出前添加适当的标头。

答案 6 :(得分:0)

我知道我听起来很愚蠢,但为什么不安装wamp或lamp?这是一种真正的“解压缩和运行&amp;voilà”类型的解决方案,可以免除您的麻烦。