Page 1 of 1

Resetting html page/form while using header() and ob_*

Posted: Wed Jul 30, 2008 6:30 pm
by jonmack3
I'm trying to authenticate users, diverting authenticated users to one of two web pages depending on a value in the same table that has their username/password. The php and html form appears to be working correctly, but there are two things that are happening when the page is refreshed that I would rather not:

1. The username stays at its pre-refresh value.
2. The last error message received ("Username must contain...", "Password must contain...", "Username/password combination...") remains.

I've tried setting form value = "", unset($_POST), and various $_POST[] values to "", all to no avail. I'm almost positive this is a header issue, but I'm not sure how to fix it.

Any ideas? (Also, I'm rather new to php, so comments on any other part of the code or the format of this forum post that would improve it would be helpful.)

Thank you.

login.php:

Code: Select all

<?php
    //ob_start();
?>
<html>
    <head>
    </head>
    <body>
        <form action="login.php" method="post">
            <p>
                <label for="username">Username</label>
                <input type="text" name="username" id="username" value="" />
            </p>
            <p>
                <label for="password">Password</label>
                <input type="password" name="password" id="password" />
            </p>
            <p>
                <input type="submit" name="login" value="Sign in" />
            </p>
        </form>
 
        <?php
            // test user login
            if (isset($_POST["login"]))
            {
                include_once ("msffl.php");
                // check for username not valid
                if (!validate($_POST["username"]))
                {
                    echo "<p>Username must contain only alphanumeric characters (a-z, A-Z, 0-9), and may not be blank.</p>";
                }
                // check for password not valid
                else if (!validate($_POST['password']))
                {
                    echo "<p>Password must contain only alphanumeric characters (a-z, A-Z, 0-9), and may not be blank.</p>";
                }
                // username/password valid
                else
                {
                    // compare username/password
                    connect();
                    $user_type = compare($_POST["username"], md5($_POST["password"]));
                    // administrator signing in, load admin page
                    if (!strcasecmp($user_type, "A"))
                    {
                        //header("Location: admin/admin.php");
                    }
                    // player signing in, load player page
                    else if (!strcasecmp($user_type, "P"))
                    {   
                        //header("Location: players/player.php");
                    }
                    // username/password combination incorrect
                    else
                    {
                        echo "<p>Username/password combination incorrect; please try again.</p>";
                    }
                }
                //ob_end_flush();
            }
        ?>
    </body>
</html>
msffl.php:

Code: Select all

<?php
    // connects to a mySQL database, printing error message if unable
    function connect()
    {
        @mysql_pconnect("localhost", "----", "----")
            or die("Could not connect to MySQL server");
        @mysql_select_db("fantasy_football") or die("Could not open database");
    }
 
    // compares username and password, returns user type if they match, blank otherwise
    function compare($username, $password)
    {
        $query = "SELECT player_id, password, user_type from players WHERE player_id = '"
            .$username."' and password = '".$password."'";
        $result = mysql_query($query);
        if (mysql_num_rows($result) == 0) $user_type = "";
        else $user_type = mysql_result($result, 0, "user_type");
        return $user_type;
    }
    
    // closes the database
    function close_db()
    {
        mysql_close();
    }
    
    // validates that no [:punct:] characters are present, and that string is not null
    function validate($string)
    {
        $valid = true;
        if (preg_match("/[[:punct:]]/", $string) || strlen($string) == 0)
        {
            $valid = false;
        }
        return $valid;
    }
?>

Re: Resetting html page/form while using header() and ob_*

Posted: Thu Jul 31, 2008 2:09 pm
by infolock
have you looked into using sessions?

Re: Resetting html page/form while using header() and ob_*

Posted: Thu Jul 31, 2008 3:42 pm
by jonmack3
Ye...es, but I'm a bit leery of using them. I'm still pretty new to php, and I'd like to make sure I understand basic functionality first before I move up. Is there something about the interplay between headers and $_POST that makes this impossible? Are sessions going to be required?

I'm guessing these errors would go away if I could guarantee that, after a refresh or submit, the form would always load before the if statement is checked. Is there an easier way than sessions to ensure this?

Again, thanks for any and all help.

Re: Resetting html page/form while using header() and ob_*

Posted: Thu Jul 31, 2008 4:34 pm
by ody3307
jonmack,
I'm looking at line 44, code is below:
if (!strcasecmp($user_type, "A"))

You are testing for a "not equal" condition. If the database returns "A" (in this case) your code would not direct to the Admin page. It is the same with the next section of code.

It looks like you mean to test for "if $user_type == "A" then jump to admin.php? If that is the case, remove the "!" sign and this should work.

The reason you are seeing the post variables maintain their value after the submit button is pressed is because php is doing just what it is supposed to (if I am reading the code right, LOL).

The post values are passed to the receiving page (in this case its the same page), php then checks for instructions. When there is nothing to do, it waits for the next action.

Re: Resetting html page/form while using header() and ob_*

Posted: Thu Jul 31, 2008 6:57 pm
by jonmack3
You are testing for a "not equal" condition. If the database returns "A" (in this case) your code would not direct to the Admin page. It is the same with the next section of code.
If I'm reading the manual correctly, strcasecmp returns 0 if the two are equal, and 0 is php's boolean false, so the negation should be there. This is borne out by the result: with the !'s in place, when the username and password are correct, php loads the correct external page.

My problem is that if a user puts in a bad username or password and gets an error message ("Username/password combination incorrect...", "Username must contain...", etc), then puts in a correct one, then goes back to the login page, the username and error message is still there, and it would be nice if the form reset.

You're right, though; the only potential issue from that could be security-related, but the password resets in every case, so it probably won't be a problem. I suppose I could always use some javascript to clear the form on a new load.

In retrospect, this was probably a case of me thinking behavior was abnormal when in fact it was fine. Thanks for the help, in any case. :)

Re: Resetting html page/form while using header() and ob_*

Posted: Thu Jul 31, 2008 7:18 pm
by ody3307
Interesting.
Just went to php.net to read up on strcasecmp(). I don't use this one much at all. You are correct that a match evaluates to 0. And more importantly, it works here.

But, in php a boolean false evaluates to false, not 0. In some cases 0 will also evaluate to false but not always. It can give unexpected results. There is a good description here: http://us.php.net/manual/en/function.is-bool.php (look at example #1).

One of the nice things about coding; there are a variety of ways to solve the same problem. I wouldn't have thought of this one.

Sorry I didn't help with the problem.