带有ob_start()和ob_end_flush()的PHP头问题

带有ob_start()和ob_end_flush()的PHP头问题,php,header,Php,Header,当我在页面的开头使用ob\u start(),在结尾使用ob\u end\u 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=".$

当我在页面的开头使用
ob\u start()
,在结尾使用
ob\u end\u 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();
在header.php中,我还添加了ob_start()并在footer.php中添加了ob_end_flush(),但我认为这不是问题,尽管其他页面使用我上面写的相同脚本运行

我得到的错误是:

警告:无法修改标题信息-标题已在第9行的D:\xampp\htdocs\project\add\u book\u hours.php中发送


在第一个
之前是否有空格?我认为问题可能是您在向输出发送其他内容后试图更改标题。即使在使用缓冲时,我也不认为这是可能的。我认为您需要调用ob_end_clean()来丢弃当前缓冲区并写入头信息。

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

<?php ob_start();?> --- THERE IS A LINE RETURN HERE ---
--- SPACES OR TABS ---<?php include_once("header.php"); ?> --- LINE RETURN ---
--- AND HERE ---<?php global $db;
     ...
——这里有一个换行符---
---空格或制表符-----换行符---

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

if($delHourExist)
{
  if ( headers_sent($path, $lineno) ) {
    echo '<pre>Debug: output started at ', $path, ':', $lineno, "</pre>\n";
  }
  header("location: edit_delivery_hours.php");
}
if($delHourExist)
{
如果(发送的标题($path,$lineno)){
echo“调试:输出从“,$path,”:“,$lineno,”\n”开始;
}
标题(“位置:edit_delivery_hours.php”);
}

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



您遇到的问题是什么?标题问题是什么?另外,我认为嵌套
ob\u start
调用不是一件好事。请阅读这个关于防止SQL注入的问题。这与您当前的问题无关,但它是非常有用的信息。警告消息是否包含两个位置a)导致“第一个”内容输出的文件和行,以及b)导致警告的文件和行?类似PHP的警告:无法修改标题信息-标题已经由文件2中的LineNumber2行发送(输出从文件1:linenumber1开始),您可以将add_book_hours.PHP的第9行添加到您的问题中吗?没有空格,也没有UTF-8 BOM(例如,我不知道这是什么)。UTF-8 BOM标记是一个隐藏字符。你需要查找一个编辑器,你可以用它来显示这个(例如记事本++)(将+1,但票数不足)空白和BOM总是第一件要检查的事情。不要忘记尾随的换行符。这个代码示例中有很多空白。在大多数情况下,源文件中只需要一个PHP块。这会省去一些痛苦。在我必须写
ob\u end\u clean()
的地方,我已经在脚本末尾写了
ob\u end\u flush()
。在执行输出(包括缓冲输出生成)之前,您可以在任何时候完全更改标题。没有空格,但有一行新的制表符,请告诉我一件事,如何在没有制表符或新行的情况下缩进您所显示的代码?我同意Scott的观点:您有很多不必要的
,您需要使用制表符或空格进行缩进。您需要换行以更改行。关键是:不要在php标记之外使用它们。忽略PHP标记中的空白。php标记外的空白不会被忽略,并输出到浏览器。如果在header()调用之前php标记外有空格,则会导致错误,因为在header()之前有输出。在我的示例中,所有的换行符和空格都在php标记中。在您的代码中,它们都在php标记之外。这次它不会显示nat头问题并重定向到编辑页面。。谢谢你,陛下。。。这不应该解决任何问题。它只是添加了调试输出。在这种情况下,你不应该接受我的回答作为你问题的解决方案(事实并非如此)。你绝对确定你没有改变其他事情吗。你测试页面的方法和以前完全一样吗?我只是重写代码,重写所有行,但这次我又得到了标题警告,这让我很讨厌……你使用哪一个版本的php(和构建,即从哪里获得的php版本)?询问,因为包含两个位置(导致输出的位置和导致警告的位置)的“完整”警告消息将非常有助于调试这些问题
if($delHourExist)
{
  if ( headers_sent($path, $lineno) ) {
    echo '<pre>Debug: output started at ', $path, ':', $lineno, "</pre>\n";
  }
  header("location: edit_delivery_hours.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');
?>