开发者

PHP Header Location gets sent even inside an output buffer?

开发者 https://www.devze.com 2023-03-08 11:45 出处:网络
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 he

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');
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号