PHP 输出缓冲和标头位置


PHP output buffering and header location

在我们的一个服务器上有一个非常古老的php身份验证脚本,看起来像这样:

ob_start();
$log = new Auth();
// returns true
$checkSession = $log->checkLog();
 if(!$checkSession){
    header("Location: ../index.php");
    exit();
  }else{
    include "content/".$_GET["content"].".php";
   }
$content = ob_get_contents();
ob_end_clean();
include "../".WEBROOT_TEMPLATE_FILE;

它总是运行顺利(经过身份验证的用户能够访问该页面,未经身份验证的用户被重定向到主页(......直到今天!

出于某种完全未知的原因,当用户尝试从 access 2000 数据库生成的链接访问其中一个服务器页面时,他们总是被重定向到 index.php。

奇怪的是,将URL直接粘贴到浏览器中时,它可以正常工作。url 完全相同,$_SERVER 变量在这两种情况下也完全相同。我什至检查了也相同的HTTP标头。

另外,如果我评论重定向,它确实有效:

 if(!$checkSession){
    //header("Location: ../index.php");
    //exit();
  }else{
    // that part is executed
    include "content/".$_GET["content"].".php";
   }

有人在这里遇到了同样的问题,但遗憾的是没有收到任何有效的答案:当标头(位置:xxx(在里面时,PHP if-语句被忽略

知道吗?

提前感谢您的帮助,

编辑:找到解决方案

出于某种原因,apache 服务器不喜欢由 access 2000 数据库生成的 http 请求,并发出了一个带有修改标头的新请求(尤其是 http accept(......可悲的是,第一个请求没有初始化任何会话......因此重定向到索引.php。

所以(丑陋但有效的(解决方案对我来说是:

if($_SERVER['HTTP_ACCEPT']!="*/*"){
// Do your stuff
}

试试这个:

header("Location: http://site.com/index.php");

正如@MonkeyMonkey所说,这很可能与标头/cookie已经发送的事实有关,当脚本到达会话身份验证并重定向时,它无法重新发送它们。

如果将error_reporting设置为 E_ALL,这应该会产生">警告:标头已发送"。

现在关于输出从哪里开始,这将非常难以确定。实际上,ob_start之前包含的任何文件都可以在末尾(在结尾 ?> 之后(有一个空格/制表符/换行符。

ob_start() 之后添加以下内容:

if(!isset($_SESSION)) {
      session_start();
}

在此之后,检查 $_SESSION[] 中的任何变量是否已设置并具有任何值:

if(!isset($_SESSION['username']) || $_SESSION['username'] == "") {
  header("Location: ../index.php"); //redirect unauthorized users
  exit();
}
else {
 // your code
}

注意:上面的代码只是一个示例,请在使用前根据需要进行更改。