1
    <?php
    if(isset($_SESSION['logged_in']))
    {
            header('Location: test.php');
echo "test";
    ?>

    <?php
    }
    else
    {
    ?>
            <a href="#" onclick="CallAfterLogin();"><img src="facebook-login-button.png" border="0" alt="Log in with Facebook"></a>

    <?php } ?>

After the user is login, I visit back to this file, and it just won't redirect. It did appear the echo but not the redirect, I wonder.

user3033162
  • 135
  • 2
  • 8
  • Are you calling `session_start()` before checking `$_SESSION`? – Rich Adams Nov 26 '13 at 16:55
  • 2
    Please note that the HTTP specification requires you to input a full absolute URL when using `Location` - not a relative one. The only reason it sometimes work with relative URLs is because your browser is fixing your mistake - not because it's OK. [*For 3xx responses, the location SHOULD indicate the server's preferred URI for automatic redirection to the resource. The field value consists of a single absolute URI.*](http://tools.ietf.org/html/rfc2616#section-14.30) – h2ooooooo Nov 26 '13 at 16:57
  • @user3033162 If you use a packet inspector (or Chrome/Firebugs "Network" tab), what HTTP code do you actually receive? – h2ooooooo Nov 26 '13 at 17:01
  • exit() after header() - You should be seeing "Cannot modify header information - headers already sent" message but you probably have your error reporting borked. – Mike B Nov 26 '13 at 17:01
  • @Mahendra yes I wonder why – user3033162 Nov 26 '13 at 17:02
  • @MikeB I use exit() before echo test, and I get nothing, what do u mean? – user3033162 Nov 26 '13 at 17:07
  • @user3033162 Then your error reporting is off. You're silencing a message that says you have output before sending headers. – Mike B Nov 26 '13 at 17:08
  • @MikeB do you have any solution? – user3033162 Nov 26 '13 at 17:10
  • @user3033162 Step 1 is to isolate and debug. Create this script: ` – Mike B Nov 26 '13 at 17:20

2 Answers2

0

Judging by your code, it appears that you are trying to make this redirect happen in the middle of your page - you MUST do a redirect before any output has been made. Since this is right before an a tag I am assuming you already sent the <html> tag at some point, for example.

<?php //headers ok here ?>
<!DOCTYPE html>
<?php
  // Too late for headers already.
dave
  • 62,300
  • 5
  • 72
  • 93
  • Note that you can fix this by using output buffers ([`ob_start`](http://us2.php.net/ob_start) before any output and [`ob_flush`](http://www.php.net/ob_flush) in the end of your script). – h2ooooooo Nov 26 '13 at 17:04
  • ob_start? what is that? – user3033162 Nov 26 '13 at 17:06
  • @h2ooooooo *fix* isn't the word I would use for that technique :). More like covering up bad design. – Mike B Nov 26 '13 at 17:06
  • ob_start turns on output buffering. You aren't actually "echoing" something, you are adding it to the output buffer, which allows you to, for example, set headers in the middle of your script. Then at the end you flush the buffer, outputting everything you've built up. – dave Nov 26 '13 at 17:07
  • so what is the solution? – user3033162 Nov 26 '13 at 17:08
  • why is it bad design, I have to put some html if the user is not logged in. so the header redirection should be inside the html tag. – user3033162 Nov 26 '13 at 17:09
  • @MikeB That's true, but fix is an easier word to use for newcommers to the language, as essentially it would *fix the problem*. :) OP: The reason why it's bad design is because you're essentially wasting a bunch of time on adding HTML/output to the output buffer, only to throw it all away (hence why you should `die` right after a `Location` statement). It's a waste of resources. – h2ooooooo Nov 26 '13 at 17:13
  • You figure out if they are logged in BEFORE you print the html tag. – dave Nov 26 '13 at 17:13
  • @user3033162 The way the HTTP protocol works is that it sends its packet in the following order: `[REQUEST_TYPE] [URL] [HTTP_VERSION] [HEADERS] [FORM_DATA] [SITE_OUTPUT]`, hence headers NEED to be output before the content. – h2ooooooo Nov 26 '13 at 17:15
  • @h2ooooooo You could make the same argument about the shutup operator. It's easier for noobs to use it then `isset($array['maybeExists'])`. You've launched me into a whole diatribe about why this specific question has no place here if those are the quality of answers we can expect to receive. – Mike B Nov 26 '13 at 17:18
  • @MikeB It's all a question of time. Sure, if he wants to change his entire site to have all its logic in the header on every page (even though it might not belong on anything except a specific site), then it's great. I highly doubt that you expect OP to use an MVC framework, and unfortunately a bunch of people work on limited time. I *wish* that I had all the time in the world and I could make perfect solutions every time. – h2ooooooo Nov 26 '13 at 17:22
  • I expect questions to be searchable and reusable. This one is not. All the information here is MUCH better explained and understandable in the canonical question http://stackoverflow.com/questions/8028957/headers-already-sent-by-php/8028987#8028987. It's very obvious here that OP is looking to fix, not understand therefore is not welcome here. StackOverflow isn't a quick debugging service. – Mike B Nov 26 '13 at 17:23
  • @MikeB You're more than welcome to mark this as a duplicate. No one is stopping you. :) – h2ooooooo Nov 26 '13 at 17:26
  • @MikeB I urge you to check who posted the answers as I haven't posted any answer here, and you seem to be getting mad at me. The reason I stay in the comments is because a solution suchas output buffering isn't an answer I want present in my SO history. SO culture will never change with new members, and telling them off doesn't help. I can't count how many times I've had discussions with people not bothering to escape their SQL because "I'll do it once I'm done with this". – h2ooooooo Nov 26 '13 at 17:31
  • @h2ooooooo I'm not mad at you all. You've always given good answers.. I'm waiting for someone else here to try to defend their content. – Mike B Nov 26 '13 at 17:32
  • @dave It's wrong when compared to another answer trying to send the same message. http://stackoverflow.com/questions/8028957/headers-already-sent-by-php/8028987#8028987. Someone searching for a headers problem could land HERE instead of there and be given immensely inferior answers. Let's make it easy for Google and not duplicate content. – Mike B Nov 27 '13 at 12:47
-1

try this

    <?php
    ob_start();
        if(isset($_SESSION['logged_in']))
        {
                header('Location: test.php');
    echo "test";
        ?>

        <?php
        }
        else
        {
        ?>
                <a href="#" onclick="CallAfterLogin();"><img src="facebook-login-button.png" border="0" alt="Log in with Facebook"></a>

        <?php }
ob_end_flush();
 ?>
Mahendra Jella
  • 5,450
  • 1
  • 33
  • 38
  • "*It did appear the echo but not the redirect*". Hence it **did** enter the condition which would've been impossible had the session not been started. – h2ooooooo Nov 26 '13 at 17:00
  • @user3033162 put
      ob_start() in beginning of php code
    – Mahendra Jella Nov 26 '13 at 17:20
  • @h2ooooooo u are the man! how can u know that.. pls explain my problem, I willing to learn.. – user3033162 Nov 26 '13 at 17:22
  • @user3033162 As previously mentioned, when you use `header` you specify that the PHP script should "output these headers now". Headers have to be sent before any site content (or else they do not work). That's the way the HTTP protocol works. Again: `[REQUEST_TYPE] [URL] [HTTP_VERSION] [HEADERS] [FORM_DATA] [SITE_OUTPUT]`. That means when using output buffering, whenever you echo something, you're technically doing the same as adding it to a variable (and therefore NOT outputting it until you flush the output buffer). This is why it works, because you have NOT output anything if you use `ob_`. – h2ooooooo Nov 26 '13 at 17:30