PHP标头位置甚至在输出缓冲区内发送?

时间:2011-05-25 11:19:58

标签: php header location buffering

我无法在输出缓冲区内抑制PHP位置标头。据我所知,输出缓冲区应该在刷新之前抑制标头。我还认为不应该使用ob_end_clean()发送头文件。

但是,如果你看到下面的代码,如果我取消注释标题行(第二行),我总是被重定向到谷歌并且永远不会看到'完成'。

ob_start();
//header("Location: http://www.google.com");
$output = ob_get_contents();
ob_end_clean();

$headers_sent = headers_sent();
$headers_list = headers_list();

var_dump($headers_sent);
var_dump($headers_list);

die('finished');

我需要抑制任何标头重定向,理想情况下在输出缓冲区中捕获它们,因此我知道这些条件会产生重定向。我知道我可以用curl(设置跟随重定向到假)来做到这一点,但是因为我想要缓冲的所有文件都在我自己的服务器上,所以curl证明非常慢并且占用了数据库连接的负载。

有没有人有任何建议或知道如何捕获/抑制位置标题?

谢谢, 汤姆

3 个答案:

答案 0 :(得分:2)

查看您是否可以使用header_remove功能以及headers_list。这似乎适用于IIS / FastCGI和Apache:

<?php
ob_start();
header('Location: http://www.google.com');
$output = ob_get_contents();
ob_end_clean();
foreach(headers_list() as $header) {
    if(stripos($header, 'Location:') === 0){
        header_remove('Location');
        header($_SERVER['SERVER_PROTOCOL'] . ' 200 OK'); // Normally you do this
        header('Status: 200 OK');                        // For FastCGI use this instead
        header('X-Removed-Location:' . substr($header, 9));
    }
}
die('finished');

// HTTP/1.1 200 OK
// Server: Microsoft-IIS/5.1
// Date: Wed, 25 May 2011 11:57:36 GMT
// X-Powered-By: ASP.NET, PHP/5.3.5
// X-Removed-Location: http://www.google.com
// Content-Type: text/html
// Content-Length: 8

PS:尽管ob_start文档说的是什么,但PHP将在发送输出的第一个字节时(或者当脚本终止时)发送标头。如果没有输出缓冲,您的代码必须在发送任何输出之前操作标头。使用输出缓冲,您可以交换标题操作和输出,无论如何,直到您刷新缓冲区。

答案 1 :(得分:0)

如果您阅读ob_start的手册页,则第一段是:

  

此功能将变为输出   缓冲。输出缓冲   处于活动状态,没有从中发送输出   脚本(标题除外),而不是   输出存储在内部   缓冲液中。

答案 2 :(得分:0)

  

我的理解是输出   缓冲区应该抑制标头直到   他们被冲洗了

都能跟得上:

  

虽然输出缓冲是活动否   输出从脚本发送(其他   比标题)

来源:http://us.php.net/manual/en/function.ob-start.php

您可以在发送标题之前尝试刷新:

ob_start();
flush();
header("Location: http://www.google.com");
$output = ob_get_contents();
ob_end_clean();

$headers_sent = headers_sent();
$headers_list = headers_list();

var_dump($headers_sent);
var_dump($headers_list);

die('finished');