gpt4 book ai didi

php - 使用 PHP 进行与环境无关的 301/302 重定向

转载 作者:可可西里 更新时间:2023-10-31 22:50:26 26 4
gpt4 key购买 nike

我遇到过 accidental usage FastCGI 的 Status header 。在与环境无关的脚本中使用它有优缺点吗?

header('Location: ' . $url, true, 301);

我在 Apache 2.2 上单独使用没有问题(根据 phpinfo(),服务器使用 FastCGI)。

该脚本针对 Apache 和 nginx(mod_php 和 FastCGI)。防故障解决方案是什么样的?

最佳答案

HTTP 状态代码作为 HTTP 响应第一行的一部分发出。根据Fast CGI FAQ Status header 是控制此行的服务器识别的特殊 header ,它不会发送到客户端。但是,如果它与非 FastCGI 服务器适配器一起使用,该值将被服务器忽略,并且可以发送 header 。

您已有的解决方案是尽可能与环境无关的方法。唯一的添加是在重定向后立即执行 exit 语句,以确保脚本终止。

让我们更仔细地看看幕后发生了什么。

以下PHP重定向代码

header('Location: ' . $url, true, 301);
exit;

会调用ext/standard/head.c中的C代码

PHP_FUNCTION(header)
{
[ code that just parses the arguments omitted ]

sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr);
}

依次调用main/SAPI.c中的sapi_header_op函数

[ ... ]

switch (op) {

[ ... ]

case SAPI_HEADER_ADD:
case SAPI_HEADER_REPLACE:
case SAPI_HEADER_DELETE: {
sapi_header_line *p = arg;

if (!p->line || !p->line_len) {
return FAILURE;
}
header_line = p->line;
header_line_len = p->line_len;
http_response_code = p->response_code;
break;
}

[ code that splits header line by colon, trims whitespace etc ]

[ special headers handling code, including setting 302 if Location ]

if (http_response_code) {
sapi_update_response_code(http_response_code);
}

sapi_header_add_op(op, &sapi_header);
return SUCCESS;

如果使用了FastCGI后端,添加的header最终会通过sapi/cgi/cgi_main.c中的sapi_cgi_send_headers函数发送出去

[ ... ]
if (CGIG(nph) || SG(sapi_headers).http_response_code != 200)
{
[ emit status line if cgi.rfc2616-headers is set ]

[ Handle a case where there is a user supplied status line ]

[ Handle a case where there is already a user supplied status header ]

[ if none of the above ]

if (err->str) {
len = slprintf(buf, sizeof(buf), "Status: %d %s\r\n", SG(sapi_headers).http_response_code, err->str);
} else {
len = slprintf(buf, sizeof(buf), "Status: %d\r\n", SG(sapi_headers).http_response_code);
}
[ ... ]
}
[ ... ]

请注意 sapi/apache2handler/sapi_apache2.c 中的 php_apache_sapi_send_headers 函数没有对 Status header 进行任何特殊处理,因为它不是用于模块通信。

所以通过执行上面的PHP代码

  1. HTTP 状态行中的响应代码强制为 301
  2. 添加位置 header 或替换现有 header
  3. 脚本退出,因此后续代码无法更改状态或 header

所有操作都在 SAPI 层中执行,该层是 HTTP 服务器适配器(FastCGI、Apache 模块等)之上的抽象层。这是尽可能跨环境和可靠的。

从历史上看,FastCGI 中存在阻止 301 响应正常工作的错误,但这些错误出现在 Web 服务器实现中,PHP 代码无法解决此问题。

另见:

关于php - 使用 PHP 进行与环境无关的 301/302 重定向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31925732/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com