views:

360

answers:

4

In a PHP file when I need to redirect a user and headers are already sent so I can not use php's header function, in this case which is the best method to redirect a user?

Fastest and most reliable method regardless of the users browser brand?

echo '<script type="text/javascript">window.top.location="http://localhost/";&lt;/script&gt;';

// OR

echo '<meta http-equiv="refresh" content="0;url=' .$location. '">';

UPDATE

Here is my end result code I am using now, if headers are already sent where I cannot redirect to the homepage, I just bring the homepage to me, so instead of including the body page, it will include my homepage and footer

function validlogin($url) {
    if (!isset($_SESSION['auto_id']) || ($_SESSION['auto_id']=='')) {
     $_SESSION['sess_login_msg'] = 'Please login';
     $_SESSION['backurl'] = $url;
     $temp = '';
     if (headers_sent() === false){
      header("Location: /");
      exit();
     }else{
      //header is already sent so we will just bring the homepage to us instead of going to it!!!
      include 'mainbody.inc.php';
      include 'footer.inc.php';
      exit();
     }
    }
}
A: 

I would say the second.

If the user has javascript disabled, or uses a browser without javascript, the 1st redirect will never work.

easement
You may also want to look at output buffering in PHP. This would allow you to use the server side redirect.http://us2.php.net/manual/en/ref.outcontrol.php
easement
I wonder if meta redirect is alway supported though?
jasondavis
Either way they both kill the back button.
rpflo
+7  A: 

Don't use any of these! You should always use HTTP redirects.

Use ob_start() to buffer content and avoid problem of headers already sent.

You might also try to write MVC application, where you would know whether you need to redirect before outputting anything (but with ob_start() that is not necessary).

porneL
I agree. You should be able to control the output of your application and use HTTP headers. If you absolutely cannot do this, use the 2nd option. +1 to this answer.
Lior Cohen
I don't know a lot about how ob buffer works but doesn't it put the whole page into memory before displaying, this cant be good for performance on a high traffic site can it?
jasondavis
Some tests found lots of small outputs are slower then a larger batch iirc. Needs some googling or testing.
OIS
@jasondavis: it does buffer entire page, but at the same time it avoids frequent buffer flushes. Unless your page weights gigabytes or takes many seconds to generate, it shouldn't harm performance, it may improve it (and ob_start('ob_gzhandler') will even compress it speeding up download a lot).
porneL
+2  A: 

Piggy back on porneL:

The huge problem with your methods: you kill the back button. Killing the back button is the most irritating thing on the web.

I have never found a need to redirect after headers have been sent. You should probably rethink what you're trying to do.

rpflo
I completely agree. If you need to send headers AFTER you output something, you're doing it wrong.
usoban
In my case, the only time I redirect is after submitting a form or if a user is logged out, i redirect to a login page, so the back button should not be used anyways
jasondavis
Also the reason the header is sent is because, I have a header file that is in every single page then I have the body file included below the header, now only some pages require a user be logged in, so on these pages is where I call a function that checks if logged in and if not, it trys to redirect, so since it is in the body file, the header has already been loaded before it can see if it needs to redirect
jasondavis
"so the back button should not be used anyways" ... 'should not' and 'will be' are very different things. The back button should never be broken. You can check a users status in the header file.
rpflo
+1  A: 
function Redirect($url, $permanent = false)
{
    if (headers_sent() === false)
    {
        header('Location: ' . $url, true, ($permanent === true) ? 301 : 302);
    }

    exit();
}

Redirect('http://www.google.com/', false);

Again, use ob_start();

Alix Axel
This is on the right track fro my solution, IDK why someone keeps downvoting everyone who doesn't say "output buffering", I have a GOOD idea who it is though. See with your method, I can add into my existing function, if header is already sent, then I can just include my homepage instead of redirecting to it, great solution!
jasondavis
I claim all my downvotes, for the record. You include method looks like it will work great. In the beginning of this post we knew only that you wanted to redirect. More information is always better :)
rpflo