PHP标头在foreach中不起作用

eti*_*lge 2 php oop http

这里有点奇怪的情况

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

$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']);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

jba*_*ord 6

您将Location使用200状态代码将标头返回到浏览器.

对于实际发生的重定向,3xx应该发送响应代码(通常是a 302).一个200响应代码仅仅意味着"OK,内容如下".要实现重定向,必须提供3xx响应代码.

你的代码最终会调用

header('Location: http://localhost/pages', true, 200);
Run Code Online (Sandbox Code Playgroud)

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

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


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

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

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

302打算送都将被替换的200是获取下一个呼叫建立header().

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

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

或者代替做什么header()做,并将未指定的响应代码视为含义,不要改变已经设置的内容:

public function header($string, $replace = true, $code = false) { ... }
Run Code Online (Sandbox Code Playgroud)

false0传递给PHP的(或)header()将表明.

  • 没有魔法,但你最终会调用`header('Location:http:// localhost/pages',true,200)`,这不会导致重定向. (2认同)