PHP标头在foreach中不起作用

时间:2016-01-14 11:11:49

标签: php oop http

这里有点奇怪的情况

$location = 'Location: http://localhost/pages';
//header($location); exit; works
$response->header($location)->send(); exit; //doesn't work

$response对象的类

public headers = [];

public function header($string, $replace = true, $code = 200)
{
    $this->headers[] = [
        'string' => $string,
        'replace' => $replace,
        'code' => $code
    ];

    return $this;
}

public function send()
{
    foreach ($this->headers as $header) {
        header($header['string'], $header['replace'], $header['code']);
    }
}

使用vanilla header时代码工作正常,但在使用方法时却没有。我在这里错过了什么吗?

1 个答案:

答案 0 :(得分:6)

您正在使用Location状态代码将200标题返回给浏览器。

对于实际发生的重定向,应该发送3xx响应代码(通常是302)。 200响应代码仅表示“确定,内容跟随”。要实现重定向,必须提供3xx响应代码。

您的代码最终正在调用

header('Location: http://localhost/pages', true, 200);

这不会导致浏览器将您重定向到所需的位置。

PHP本身特殊情况调用header('Location: ...')除非另有说明,否则使用302而不是保持响应代码不变。您可能需要调整代码以执行相同操作以保持与PHP相同的行为。


另外,需要注意的是,虽然每个HTTP响应只有一个响应代码,但header()允许您在每次调用时设置响应代码。

因此,如果你使用这样的代码:

$response
    ->header("Location: http://localhost/pages", true, 302)
    ->header("SomeOtherheader: value")
    ->send()
;

要发送 302将替换为200的下一次调用中设置的header()

相反,您应该做的是将设置状态代码的概念与实际设置标题内容分开,例如:

$response
    ->header("Location: http://localhost/pages"))
    ->header("SomeOtherheader: value")
    ->responseCode(302)
    ->send()
;

或代替执行header()所做的事情并将未指定的响应代码视为含义,不要更改已经设置的内容:

public function header($string, $replace = true, $code = false) { ... }
传递给PHP的false

0(或header())将表明这一点。