ob_start() 和 ob_end_flush() 的 PHP 标头问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2168956/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 05:18:57  来源:igfitidea点击:

PHP Header issue with ob_start() and ob_end_flush()

phpheader

提问by diEcho

I get header problem while I use ob_start()in the beginning of a page and ob_end_flush()at the end. Because I use header function after some query execution.

ob_start()在页面开头和ob_end_flush()结尾使用时遇到标题问题。因为我在执行一些查询后使用了 header 函数。

 ob_start();
 include_once("header.php");
 global $db;

 $countstmt="SELECT COUNT(*) FROM tbl_lib_hours dh WHERE book_id IN(SELECT book_id FROM tbl_book WHERE user_id=".$_SESSION['uid'].") ";       
 $delHourExist=$db->query($countstmt);  
 if($delHourExist){
      header("location:edit_delivery_hours.php");
 }
 ....
include_once('footer.php');
ob_end_flush();

In header.phpthere I also added ob_start();and in footer.phpi added ob_end_flush();, but I think that is not problem, although other pages are running with same script I write above

header.php 中,我还添加了ob_start(); footer.php 中我添加了ob_end_flush(); ,但我认为这不是问题,尽管其他页面正在使用我上面写的相同脚本运行

The error I am getting:

我得到的错误:

Warning: Cannot modify header information - headers already sent in D:\xampp\htdocs\project\add_book_hours.php on line 9

警告:无法修改标题信息 - 标题已发送到 D:\xampp\htdocs\project\add_book_hours.php 第 9 行

回答by Karsten

Is there any space before the first <?php?

第一个之前有空格<?php吗?

Is there an UTF8-BOM at the beginning of the file?

文件开头是否有 UTF8-BOM?

回答by Scott Saunders

There's a lot of invisible output in your code:

您的代码中有很多不可见的输出:

<?php ob_start();?> --- THERE IS A LINE RETURN HERE ---
--- SPACES OR TABS ---<?php include_once("header.php"); ?> --- LINE RETURN ---
--- AND HERE ---<?php global $db;
     ...

Quit starting and ending your php tags. Just do this:

退出开始和结束你的 php 标签。只需这样做:

<?php 
    ob_start();
    include_once("header.php");
    global $db;
    ...

Make absolutely sure that there is no output, and no whitespace outside of your tags before the call to ob_start(). If your error is on line 9, you've got a bunch of lines before that call that could be the problem. You may want to post all of those lines, numbered, so we can look at them carefully.

确保在调用 ob_start() 之前没有输出,并且标签外没有空格。如果您的错误出现在第 9 行,那么在该调用之前您有一堆可能是问题的行。您可能想要张贴所有这些行,编号,以便我们可以仔细查看它们。

回答by VolkerK

I'm a bit baffled the warning message doesn't include the location of the code that caused the first content to be sent to the client. The function headers_sent()can return that location, too. So, for debugging purposes, please try

我有点困惑,警告消息不包括导致第一个内容发送到客户端的代码的位置。函数headers_sent()也可以返回该位置。因此,出于调试目的,请尝试

if($delHourExist)
{
  if ( headers_sent($path, $lineno) ) {
    echo '<pre>Debug: output started at ', $path, ':', $lineno, "</pre>\n";
  }
  header("location: edit_delivery_hours.php");
}

回答by mariofertc

I resolve mi problem with some white spaces in my script with ob_start(); ob_end_flush(); and ob_end_clean(); So you could test your code

我使用 ob_start() 解决了脚本中一些空格的问题;ob_end_flush(); 和 ob_end_clean(); 所以你可以测试你的代码

<?php
ob_start();
include_once("header.php");

global $db;
$countstmt="SELECT COUNT(*) FROM tbl_lib_hours dh WHERE book_id IN(SELECT book_id FROM tbl_book WHERE user_id=".$_SESSION['uid'].")";
$delHourExist=$db->query($countstmt);  
if($delHourExist)
{
ob_end_flush();
ob_end_clean();
header("location:edit_delivery_hours.php");
}
include_once('footer.php');
?>
<?php
ob_start();
include_once("header.php");

global $db;
$countstmt="SELECT COUNT(*) FROM tbl_lib_hours dh WHERE book_id IN(SELECT book_id FROM tbl_book WHERE user_id=".$_SESSION['uid'].")";
$delHourExist=$db->query($countstmt);  
if($delHourExist)
{
ob_end_flush();
ob_end_clean();
header("location:edit_delivery_hours.php");
}
include_once('footer.php');
?>

回答by Kibbee

I think the problem may be that you are trying to change the headers, after you have already sent something else to the output. Even when using buffering, I don't think this is possible. I think you need to call ob_end_clean() to discard the current buffer and write header information.

我认为问题可能在于您在将其他内容发送到输出之后尝试更改标题。即使使用缓冲,我也不认为这是可能的。我认为您需要调用 ob_end_clean() 来丢弃当前缓冲区并写入头信息。