简体   繁体   中英

PHP output buffering and header location

There is a pretty old php authentication script on one of our servers which looks like this :

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;

It always worked smoothly (authenticated users were able to access to the page, unauthenticated users were redirected to the homepage) ... until today !

For some totally unknow reason, when the users try to reach one of the server pages from a link which is generated by an access 2000 database, they are always redirected to index.php.

The strange thing being that it works fine when pasting the url directly into the browser. The url is exactly the same, and the $_SERVER variable is also the same in both cases. I even checked the HTTP headers which are also identical.

Also, if I comment the redirection, it does work :

 if(!$checkSession){

    //header("Location: ../index.php");
    //exit();

  }else{
    // that part is executed
    include "content/".$_GET["content"].".php";

   }

Someone had the same problem here, but sadly didn't receive any valid answer : PHP if-statement ignored when header(Location: xxx) is inside

Any idea ?

Thanks in advance for your help,

edit : found the solution

For some reason, the apache server didn't like the http request which was generated by the access 2000 database and issued a new one with modified headers (especially the http accept)... Sadly, the first request didn't initialize any session ... hence the redirection to index.php.

So the (ugly but working) solution is, for me :

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

尝试这个:

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

As @MonkeyMonkey said it most likely relates to the fact that headers/cookies are already sent and by the time the script reaches the session authentication and redirects it can't resend them.

This should yield a " Warning: headers already sent " if you set your error_reporting to E_ALL.

Now about where output started, that would be pretty tricky to pinpoint. Virtually any file included before the ob_start could have a space/tab/newline at the end (after the ending ?> ).

Add this after ob_start() :

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

and after this, check any variable from $_SESSION[] if it is set and has any value:

if(!isset($_SESSION['username']) || $_SESSION['username'] == "") {

  header("Location: ../index.php"); //redirect unauthorized users
  exit();
}
else {
 // your code
}

Note: Above code is just a example, change it as per your need before using.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM