I am having trouble suppressing a PHP Location Header from inside an output buffer. It is my understanding that output buffers should suppress headers until they are flushed. I also thought that no headers should be sent with ob_end_clean().
However if you see the code below, if I uncomment the header line (second line) I always get redirected to google and never see 'finished'.
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');
I need to suppress any header redirects, ideally catching them in the output buffer so I know those conditions will produce a redirect. I know I can do this with curl (setting follow redirects to false), but as all the files I want to buffer are on my own server curl is provin开发者_如何学编程g very slow and tying up loads of db connections.
Does anyone have any suggestions or know of any way of catching/suppressing Location Headers?
Thanks, Tom
See if you can use header_remove
function along with headers_list
. This seemed to work on IIS/FastCGI and 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: despite of what the ob_start documentation says, PHP will send headers when it is about to send the first byte of output (or when the script is terminates). Without output buffering, your code must manipulate headers before sending any output. With output buffering, you can interleave header manipulation and output anyway you like until you flush the buffer.
If you read the manual page for ob_start the first paragraph is:
This function will turn output buffering on. While output buffering is active no output is sent from the script (other than headers), instead the output is stored in an internal buffer.
It is my understanding that output buffers should suppress headers until they are flushed
Nope:
While output buffering is active no output is sent from the script (other than headers)
Source: http://us.php.net/manual/en/function.ob-start.php
You can try flushing before sending headers though:
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');
精彩评论