2011-05-25 84 views
3

我无法从输出缓冲区中抑制PHP位置标题。我的理解是输出缓冲区应该压缩标题直到它们被刷新。我也认为不应该使用ob_end_clean()发送头文件。即使在输出缓冲区内也会发送PHP标头位置?

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

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被证明非常慢并且占用了大量的db连接。

有没有人有任何建议或知道任何方式捕捉/抑制位置标题?

感谢, 汤姆

回答

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将发送头时,它是关于当脚本终止发送输出的第一个字节(或)。在没有输出缓冲的情况下,您的代码必须在发送任何输出之前操作标题。通过输出缓冲,您可以交错标题操作和输出,直到您刷新缓冲区。

+0

(几乎)完美!令人讨厌的是我的服务器运行在PHP 5上。2仍然,但我找到了一个解决方法: foreach($ headers_list作为$ header) { $ name_pos = strpos($ header,':'); ($ name_pos && strlen($ header)!= $ name_pos) header(substr($ header,0,$ name_pos + 1)); } } 这将删除所有已设置的标题(最重要的是位置标题)。谢谢您的帮助! – lopsided 2011-05-25 12:22:23

+0

Awww ...刚刚注意到'header_remove'在PHP 5.3.0或更高版本中可用。 – 2011-05-25 13:33:25

0

如果你读了手册页ob_start第一段是:

,此功能将关闭输出 缓存上。虽然输出缓冲 处于活动状态,但没有输出从 脚本(除标头外)发送,而不是 输出存储在内部 缓冲区中。

+0

见上面我的意见,汤姆。 – lopsided 2011-05-25 12:29:32

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

从我上面的测试和萨尔曼的解决方案验证,标题不会从输出缓冲区内发送到浏览器。我读这一行意味着从输出缓冲区内发送的任何头文件都会立即应用到父脚本头文件中,而不管缓冲脚本中发生了什么。从我所看到的情况来看,情况似乎如此。 Tom – lopsided 2011-05-25 12:28:37

+0

感谢您的帮助! – lopsided 2011-05-25 12:29:42