Redirect does not interrupt script interpretation?

1

I may be missing something, but by no means can I see what. I have a simple login code that is behaving (at least it seems to me) in a strange way.

index.php:

session_start();
if(isset($_SESSION['error'])) {
    echo $_SESSION['error'];
    unset($_SESSION['error']);
}
?>
<form method="POST" action="process.php">
    username
    <input type="text" name="username">
    password
    <input type="password" name="password">
    <input type="submit">
</form>

process.php

session_start();
if($_SERVER['REQUEST_METHOD'] == 'POST') {
    if($_POST['password'] == 'password' && $_POST['username'] == 'miguel') {
        $_SESSION['error'] = 'Loggedin Success';
        header('Location: index.php');
    }
    $_SESSION['error'] = 'Wrong details (username/password)';
    header('Location: index.php');
}
$_SESSION['error'] = 'NO POST REQUEST';
header('Location: index.php');

Well, what is happening with this code is that either I put the wrong credentials or certain (miguel / password) it will always interpret the last block

$_SESSION['error'] = 'NO POST REQUEST';
header('Location: index.php');

How is this possible? Since we have gone through redirects before, should not the script (process.php) be interrupted / canceled at that time and redirected to the destination?

If you put elses containing the blocks the code already does the "supposed":

session_start();
if($_SERVER['REQUEST_METHOD'] == 'POST') {
    if($_POST['password'] == 'password' && $_POST['username'] == 'miguel') {
        ...
    }
    else {
        ...
    }
}
else {
    ...
}

But why are they needed in this framework? I always thought that when interpreting a header('Location: ...'); the interpretation of the script itself would be interrupted

    
asked by anonymous 26.11.2016 / 13:55

1 answer

4

PHP's header function only sends an HTTP header to the browser, and the HTTP protocol allows multiple header per request or response. So PHP does not know you're doing a redirect, it adds all headers and it's up to the user-agent that made the request (browser, usually) to decide what to do. In case he is deciding to redirect to the last Location: header found. This should be the default protocol (but I do not have sources to confirm, if anyone knows I can comment or edit my response).

So you need to put exit or die after submitting the Location: header, so that PHP does not execute the code that sends the following:

session_start();
if($_SERVER['REQUEST_METHOD'] == 'POST') {
    if($_POST['password'] == 'password' && $_POST['username'] == 'miguel') {
        $_SESSION['error'] = 'Loggedin Success';
        header('Location: index.php');
        exit;
    }
    $_SESSION['error'] = 'Wrong details (username/password)';
    header('Location: index.php');
    exit;
}
$_SESSION['error'] = 'NO POST REQUEST';
header('Location: index.php');
// aqui não precisa de exit pois é o último
    
30.11.2016 / 20:19