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

发布于 2024-11-09 14:57:36 字数 599 浏览 4 评论 0原文

我无法从输出缓冲区内抑制 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来做到这一点(将跟随重定向设置为false),但是由于我想要缓冲的所有文件都在我自己的服务器上,curl被证明非常慢并且占用了数据库连接的负载。

有人有任何建议或知道捕获/抑制位置标头的任何方法吗?

谢谢, 汤姆

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 proving 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

只为守护你 2024-11-16 14:57:36

看看是否可以使用 header_removeheaders_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 在即将发送输出的第一个字节时(或当脚本终止时)都会发送标头。如果没有输出缓冲,您的代码必须在发送任何输出之前操作标头。通过输出缓冲,您可以按照您喜欢的方式交错标头操作和输出,直到刷新缓冲区。

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.

各自安好 2024-11-16 14:57:36

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

该函数将输出
缓冲开启。输出缓冲时
处于活动状态,没有输出从发送
脚本(标题除外),而不是
输出存储在内部
缓冲区。

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.

平定天下 2024-11-16 14:57:36

据我了解,输出
缓冲区应该抑制标头,直到
他们脸红了

不:

当输出缓冲处于活动状态时,否
输出从脚本发送(其他
比标题)

来源: 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');

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');
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文