0

I have the following PHP printExam.php page:

    <?php   
    $logins = array(
        'user' => 'pass',
        'user1' => 'pass1',
        'user2' => 'pass2',
        'user3' => 'pass3',
        'user4' => 'pass4'
    );

    // Clean up the input values 
    foreach($_POST as $key => $value) {  
        $_POST[$key] = stripslashes($_POST[$key]); 

        $_POST[$key] = htmlspecialchars(strip_tags($_POST[$key])); 
    }

    /******************************************************************************/
       if (isset($_POST['submit'])){

          $user = isset($_POST['user']) ? strtolower($_POST['user']) : '';
          $pass = isset($_POST['pass']) ? $_POST['pass'] : '';
          $report = $_POST['typereport'];

          if ((!array_key_exists($user, $logins))||($logins[$user] != $pass)) {
             showForm("Wrong Username/Password");
             exit();     
          }
          else {
    if ($report == "Clinical") {    
?>
<html>
<head>
</head>

<body>
CLINICAL PAGE
</body>
</html>
<?php
    }
    elseif ($report == "Annual Education") {
?>
<html>
<head>
</head>

<body>
ANNUAL EDUCATION PAGE
</body>
</html>
<?php
    }
          }
       } else {
          showForm();
          exit();
       }

    function showForm($error=""){
    ?>
    <!DOCTYPE html>
    <html><head>
    <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
    <title>Certificate Printing :: Login</title>
    <script src="http://code.jquery.com/jquery-1.7.1.min.js" type="text/javascript"></script>
    <Script>
    $(function() {
      $("#user").focus();
    });
    </Script>
    </head>

    <body>

    <form id="login" action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" name="pwd">
        <h1>Log In</h1>
        <fieldset id="inputs">
            <input id="user" name="user" placeholder="Username" autofocus="" required="" type="text">   
            <input id="pass" name="pass" placeholder="Password" required="" type="password">
        </fieldset>
        <fieldset id="actions">
            <input type="radio" name="typereport" id="cbox" value="Clinical" checked="yes" /> Clinical 
            <input type="radio" name="typereport" id="cbox" value="Annual Education" /> Annual Education
        </fieldset>
        <fieldset id="actions">
            <input id="submit" name="submit" value="Log in" type="submit">
        </fieldset>
        <div class="caption"><?php echo $error; ?></div>
    </form>
    </body>
    </html>
    <?php   
    }
    ?>

For printCert.php and printCertHR.php, the very first line is:

<?php require_once('printExam.php'); ?>

What it is suppose to do is call the printExam.php page each time the user visits either pages. If the username AND password matches and depending on the selection, whether it's clinical or annual education, it should take the user to the correct page. I know the form is working correctly, because if I enter wrong username/password it shows me the error but once correct, it doesnt redirect. Any idea how to resolve it?

Please Note: the username/password is simplified for the example only!

Si8
  • 9,141
  • 22
  • 109
  • 221
  • 1
    does your script reach the expected `if` statement? can you `echo` something from there? what is the value of `$report` just right before the `if`? maybe you better to comment out that `exit;` also ... – Mahdi Jun 17 '13 at 16:34
  • 1
    not relevant to this question, but you cannot have duplicate IDs on a DOM element. your `id="cbox"` radio buttons cannot share the same id. – Marc B Jun 17 '13 at 16:35
  • If no redirection is happening, then what does the screen displays? And yeah, as the Mahdi suggested, why not print some messages and see if it has reached that point? – Suthan Bala Jun 17 '13 at 16:36
  • I edited my question above to reflect your request. – Si8 Jun 17 '13 at 16:36
  • I get this error now: `printcert.php Warning: Cannot modify header information - headers already sent by (output started at /home/web/i/interfaithmedical.com/htdocs/checksite/printExam.php:45) in /home/web/i/interfaithmedical.com/htdocs/checksite/printExam.php on line 46` – Si8 Jun 17 '13 at 16:38
  • Before submit condition code I would add `echo '
    '; print_r($_POST); echo '

    ';` to check submitted data
    – michalzuber Jun 17 '13 at 16:38
  • 'Headers already sent' Is because of the blank lines as I mention in my answer – jman Jun 17 '13 at 16:39
  • I fixed it and the same error – Si8 Jun 17 '13 at 16:41
  • I think it's the `header();` that's failing because I took out that line and just added an `echo` and it prints out in the correct condition. – Si8 Jun 17 '13 at 16:49
  • 1
    **"You can't have your cake and eat it too"**. Which translated in PHP means, you can't have an `echo` with a `header` mixed into one. It's either/or. **Pick "ONE"**. – Funk Forty Niner Jun 17 '13 at 16:50
  • I agree with you. I think it's the `header();` that's failing because I took out that line and just added an `echo` and it prints out in the correct condition. – Si8 Jun 17 '13 at 16:52
  • I just noticed something, the URL does change to the correct page but the page still shows the signon page. Any idea? – Si8 Jun 17 '13 at 16:56
  • The code is working fine to me when set to redirect to google for one and yahoo for the other. So there is no fault in the code, you have something else missing when you put it into your entire code. – Suthan Bala Jun 17 '13 at 17:03

5 Answers5

3

The 'Location' header command in PHP should be followed with an exit;

Otherwise the code below is executed, ie any output is sent to the browser.

See the examples from the PHP header page:

<?php
header("Location: http://www.example.com/"); /* Redirect browser */

/* Make sure that code below does not get executed when we redirect. */
exit;
Déjà vu
  • 28,223
  • 6
  • 72
  • 100
  • Did not solve the error. The signon page keeps refreshing if the username/password is correct. – Si8 Jun 17 '13 at 16:44
  • It keeps refreshing? So you're setting the header everytime the site is loaded. – Andre Jun 17 '13 at 16:44
  • I think it's the `header();` that's failing because I took out that line and just added an `echo` and it prints out in the correct condition. – Si8 Jun 17 '13 at 16:49
2

Location (or any other header) needs to be the first thing echoed by your script. Remove the blank lines in your script.

jman
  • 11,334
  • 5
  • 39
  • 61
  • Right after IF statement, header is the first line. – Si8 Jun 17 '13 at 16:32
  • 2
    There are blank lines before that. – jman Jun 17 '13 at 16:34
  • Instead `header ("Location: printCert.php");` it should be `header("Location: printCert.php");` – michalzuber Jun 17 '13 at 16:36
  • 1
    I have another form which has space between `header` and `()` and that works just fine. I think it's the `header();` that's failing because I took out that line and just added an `echo` and it prints out in the correct condition. – Si8 Jun 17 '13 at 16:50
  • Space doesn't matter, its the blank lines. – jman Jun 18 '13 at 18:21
2

You have contents being displayed before the header is being called (as for your comment to Rob W). The way to get around it is, put ob_start(); at the top of your php code, and ob_end_flush(); at the end of your code so the header can be called anywhere in between your code.

Suthan Bala
  • 3,209
  • 5
  • 34
  • 59
  • This is the right answer. Header cannot be used when anything else has been outputted before. – Dany Caissy Jun 17 '13 at 16:47
  • 1
    I think it's the `header();` that's failing because I took out that line and just added an `echo` and it prints out in the correct condition. – Si8 Jun 17 '13 at 16:50
1

After your elseif ($report == "Annual Education") { block, try print_r($report) - ensure it's what you are expecting...

if ($report == "Clinical") {
    header ("Location: printCert.php");
}
elseif ($report == "Annual Education") {
    header ("Location: printCertHR.php");
}
print_r($report);

Also, try monitoring FireBug's NET tab (or CHROME's)

Rob W
  • 9,134
  • 1
  • 30
  • 50
  • I get this error now: `printcert.php Warning: Cannot modify header information - headers already sent by (output started at /home/web/i/interfaithmedical.com/htdocs/checksite/printExam.php:45) in /home/web/i/interfaithmedical.com/htdocs/checksite/printExam.php on line 46` – Si8 Jun 17 '13 at 16:40
1

Is it possible that you might need to use PHP's Output Buffer to fix that? When the script is parsed, having the output of the form in a function might be throwing it off, as the function will be parsed before the rest of the script is run.

Also, you should use strcmp for comparing strings, not the == sign. strcmp vs ==

Try using the output buffer functions and see if that fixes it. it's gonna look something like this:

function showForm($error=""){
ob_start(); ?>
<!DOCTYPE html>
<html><head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<title>Certificate Printing :: Login</title>
<script src="http://code.jquery.com/jquery-1.7.1.min.js" type="text/javascript"></script>
<Script>
$(function() {
  $("#user").focus();
});
</Script>
</head>

<body>

<form id="login" action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" name="pwd">
    <h1>Log In</h1>
    <fieldset id="inputs">
        <input id="user" name="user" placeholder="Username" autofocus="" required="" type="text">   
        <input id="pass" name="pass" placeholder="Password" required="" type="password">
    </fieldset>
    <fieldset id="actions">
        <input type="radio" name="typereport" id="cbox" value="Clinical" checked="yes" /> Clinical 
        <input type="radio" name="typereport" id="cbox" value="Annual Education" /> Annual Education
    </fieldset>
    <fieldset id="actions">
        <input id="submit" name="submit" value="Log in" type="submit">
    </fieldset>
    <div class="caption"><?php echo $error; ?></div>
</form>
</body>
</html>
<?php   
return ob_get_flush();
}

Output Buffers (php.net)

Community
  • 1
  • 1
Goldentoa11
  • 1,700
  • 2
  • 17
  • 29
  • The signon page keeps refreshing – Si8 Jun 17 '13 at 16:46
  • interesting. For me, that code works. I get a 404 because I don't have printCert.php on my machine – Goldentoa11 Jun 17 '13 at 16:51
  • I'm curious, what is in the printExam.php file? is it possible that that file might be redirecting you back to the original file? – Goldentoa11 Jun 17 '13 at 16:53
  • I just noticed something, the URL does change to the correct page but the page still shows the signon page. Any idea? – Si8 Jun 17 '13 at 16:54
  • 1
    > For printCert.php and printCertHR.php, the very first line is: `` that's gonna throw you into an "infinite loop" because All that logic is going to run again after the headers have been sent, so it'll check all the username and passwords again, so you'll be told you're not logged in, so you'll have to log back in, which will then redirect you to the appropriate page, which then will require the auth, which then will kick you back to printExam.php, which... :) – Goldentoa11 Jun 17 '13 at 16:57
  • Ahhhhh I see, well isn't require_once() just a one time sign on? What do you think is a better option? I am just trying to protect the two pages until a username/password has been authenticated. – Si8 Jun 17 '13 at 16:59
  • 1
    `require_once` is during the life of the request. Everytime a new request is made (`header`) it can be included again. `require_once` is the PHP way of preventing Multiple Inclusion, if you're familiar with C/C++. As for how I would do it, I'd use Sessions. If the login works, set a session variable, (persists between requests), and check that after the authentication to see if they're logged in. – Goldentoa11 Jun 17 '13 at 17:02
  • 1
    @SiKni8 To add to `Goldentoa11's` comment above; if you're going to use `sessions`, **Remember this:** You will need to have `session_start();` at the **top** of all or most pages. – Funk Forty Niner Jun 17 '13 at 17:08
  • @Goldentoa11 I updated my code, so I do not use the header(); rather display the webpages based on the selection. But now I see both HTML pages. Any idea why? – Si8 Jun 17 '13 at 17:12
  • Nevermind, because I was sanitizing, the ANNUAL EDUCATION was not checking correctly. I made it ANNUALEDUCATION and it worked just fine. Thanks to you both for the help. – Si8 Jun 17 '13 at 17:18
  • @SiKni8 Glad to see you found your solution. – Funk Forty Niner Jun 17 '13 at 17:21