Field Validation Question

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

User avatar
Celauran
Moderator
Posts: 6427
Joined: Tue Nov 09, 2010 2:39 pm
Location: Montreal, Canada

Re: Field Validation Question

Post by Celauran »

Pavilion wrote:

Code: Select all

<label for="password">Password</label> // this line sets up the label
<input type = "password" name="password" /> // this line sets up the input control and gives it a "password" type.
Right on both counts.
Pavilion wrote:

Code: Select all

<?php if (isset($errors['password'])): ?> // Other than starting an "if" statement, I have no idea what this line is doing. If I had to guess... I'd say it was "grabbing" any error for later reference.
The syntax used above is functionally equivalent to if { }.
At the beginning of the script, we checked if $_SESSION['errors'] existed. That is to say, we checked if register_post2.php directed us back here with error messages. If it did, we assign it to the local $errors variable (technically an unnecessary step, but it saved me from rewriting code). On any given page load, we may or may not have been redirected from register_post2.php; if we're not redirected, then clearly there aren't any error messages. That said, what we're doing here is checking if any errors have been returned to this page and displaying them if they have. We're storing the errors in an array so each error can be displayed next to the relevant field.
Pavilion wrote:

Code: Select all

<span class="error"><?php echo $errors['password'];?></span> // I have no idea what this line is doing. It seems to be setting up an echo, but when I leave the password field blank - the only error message I receive is the one set up in register_post2.php. In addition to not understanding the reason for an "echo" - I also don't understand why the <span> tag is necessary - what is it doing?
This was mostly explained above. If an error was sent back from register_post2.php, we display it here. Why it's not displaying an error about a blank password I cannot say without seeing your new code for register_post2.php. Finally, I used a span tag because it's an inline element and could thus be displayed next to the input element.
Pavilion
Forum Contributor
Posts: 301
Joined: Thu Feb 23, 2012 6:51 am

Re: Field Validation Question

Post by Pavilion »

Thanks Celauran - your explanations really have helped increase my understanding. Essentially - and to put it very simply - the interaction between register.php and register_post2.php is a two way street. Register2.php "sends" $_POST variables to register_post2.php. But register_post2.php sends errors to register.php as well. Best practice is to write script accounting for all the different scenarios....
Celauran wrote:This was mostly explained above. If an error was sent back from register_post2.php, we display it here. Why it's not displaying an error about a blank password I cannot say without seeing your new code for register_post2.php.
:D The good news is, I managed to figure out the error. And now, if the password field is left blank, then register_post2.php redirects back to register.php with an error message.

However - as a further exercise in learning, I decided to add a input control for verifying the password. Following are the affected lines of code:

Code: Select all

<label for="password">Password</label>
<input type = "password" name="password" />
<?php if (isset($errors['password'])): ?>
<span class="error"><?php echo $errors['password'];?></span>
<?php endif; ?><br />

<label for="password2">Verify Password</label>
<input type = "password" name="password2" />
<?php if (isset($errors['password2'])): ?>
<span class="error"><?php echo $errors['password2'];?></span>
<?php endif; ?><br />
The "password2" (Verify Password) control shows up on the form just fine and I am able to enter the password again. So... now my next problem is throwing an error message if (!$_POST['password'] <> !$_POST['password2']).

I know this may be sloppy - and fully accept your analysis if you tell me it is sloppy. But, in my mind, it didn't make sense to "send" any non-matching password to register_post2.php. Because the "password2" control simply exists to verify "password" - it makes no sense to "send" anything to register_post2.php. Instead, verification should be completed in register.php. (or - at least that is my thinking). So... with that in mind... I inserted the following code directly beneath the "password2" code block.

Code: Select all

<?php
if (!$_POST['password'] <> !$_POST['password2'])
{
$errors['password'] = "Passwords do not match.";
}
?>
This code block does not work. It doesn't work if I insert it in register_post2.php either. If my passwords don't match, the data is written to my table anyway and no error message is thrown.

Pavilion
User avatar
Celauran
Moderator
Posts: 6427
Joined: Tue Nov 09, 2010 2:39 pm
Location: Montreal, Canada

Re: Field Validation Question

Post by Celauran »

It has to go in register_post2.php because that's where the form is processed, as dictated by the form's action. As for the code not working, why the use of the NOT operator? Try this way:

Code: Select all

if ($_POST['password'] != $_POST['password2'])
{
    $errors['password2'] = "Passwords do not match.";
}
With regards to sloppiness, I think keeping these two pages separate simply adds unnecessary complexity and hinders code readability given the relative simplicity of the task at hand.
Pavilion
Forum Contributor
Posts: 301
Joined: Thu Feb 23, 2012 6:51 am

Re: Field Validation Question

Post by Pavilion »

Celauran wrote:It has to go in register_post2.php because that's where the form is processed, as dictated by the form's action. As for the code not working, why the use of the NOT operator? Try this way:

Code: Select all

if ($_POST['password'] != $_POST['password2'])
{
    $errors['password2'] = "Passwords do not match.";
}
Thank you Celauran - it does work in register_post2.php. And after you mentioned that the form is processed in register_post2.php (as dictated by the form's action), it makes perfect sense to put the code block in register_post2.php.

Also - you asked:
why the use of the NOT operator
The NOT operator is what I would use in VB. So... when I googled php operators and found this - "x <> y Not equal True if x is not equal to y 5<>8 returns true" - it only made sense to me, as I've been using that operator for 20 years. :) But... now I know != does the same thing. May I ask what the difference is?

With regards to your following comment.
With regards to sloppiness, I think keeping these two pages separate simply adds unnecessary complexity and hinders code readability given the relative simplicity of the task at hand.
If you'll recall, earlier in this discussion (and in another thread), I asked about combining html and php scripts. I too have this concern. In working through this exercise, with you, I've found myself wondering the same thing. If a programmer has to go through all the trouble of passing variables and such, then why separate files. I guess - in one way - we're right back where our discussion started.

Mind you... I've learned much along the way, so this has not been a waste of time. Not by a long shot.

But.. I would like to go back to the concept of when it is appropriate to use two files, and when it appropriate to simply house everything in one file.

Pavilion
User avatar
Celauran
Moderator
Posts: 6427
Joined: Tue Nov 09, 2010 2:39 pm
Location: Montreal, Canada

Re: Field Validation Question

Post by Celauran »

Pavilion wrote:
why the use of the NOT operator
The NOT operator is what I would use in VB. So... when I googled php operators and found this - "x <> y Not equal True if x is not equal to y 5<>8 returns true" - it only made sense to me, as I've been using that operator for 20 years. :) But... now I know != does the same thing. May I ask what the difference is?
I was asking about the NOT operator (or negation, if you prefer) before $_POST, not the NOT EQUAL operator. Your original code was, effectively "if not password does not equal not password2", which doesn't really make much sense.

I don't employ any hard and fast rule with regards to splitting things into multiple files or keeping them together. Once the complexity gets such that I feel the need to begin abstracting things away, then I'll generally employ an MVC approach and opt for a complete separation of concerns.
Pavilion
Forum Contributor
Posts: 301
Joined: Thu Feb 23, 2012 6:51 am

Re: Field Validation Question

Post by Pavilion »

Celauran wrote:
Pavilion wrote:
why the use of the NOT operator
The NOT operator is what I would use in VB. So... when I googled php operators and found this - "x <> y Not equal True if x is not equal to y 5<>8 returns true" - it only made sense to me, as I've been using that operator for 20 years. :) But... now I know != does the same thing. May I ask what the difference is?
I was asking about the NOT operator (or negation, if you prefer) before $_POST, not the NOT EQUAL operator. Your original code was, effectively "if not password does not equal not password2", which doesn't really make much sense.
OK... confusion setting back in. :?

Code: Select all

!$_POST['password']
Means "NOT" Password???? I take it an exclamation point is "not" in php. You are probably LOL right now (I know I am). But... seriously... I hadn't realized. That explains more than you think it does. So much of the time when I was reading if statements in your coding, I was thinking to myself that the statement looked as if it was testing for true instead of false. I was actually going to ask you about that, but it wasn't as high on my list of questions as others. :lol:
I don't employ any hard and fast rule with regards to splitting things into multiple files or keeping them together. Once the complexity gets such that I feel the need to begin abstracting things away, then I'll generally employ an MVC approach and opt for a complete separation of concerns.
So... for you... what is complex. Trust...me working through this exercise has been pretty complex for me. :lol:

I guess to use (or not to use) separate files is a "learn as you go" type of thing....

Pavilion
Last edited by Pavilion on Fri Mar 02, 2012 3:35 pm, edited 1 time in total.
User avatar
Celauran
Moderator
Posts: 6427
Joined: Tue Nov 09, 2010 2:39 pm
Location: Montreal, Canada

Re: Field Validation Question

Post by Celauran »

Yes, the exclamation point is the NOT operator in PHP.
Pavilion
Forum Contributor
Posts: 301
Joined: Thu Feb 23, 2012 6:51 am

Re: Field Validation Question

Post by Pavilion »

Well... after I've had some time to absorb everything I've learned today... I'm going to try and merge the two files. (I'll look at your original code before merging).

Once I've successfully merged the files into one, I want to push forward with two other objectives.
  • Once a person successfully registers they should get a confirmation email - with a link for them to verify their email.
  • I want to find some sort of captcha to use during registration. I've one in mind - and must do some research to see if I can find open-source files for it.
At any rate - Celauran - THANK YOU!!!! You don't know how much I appreciate the time you've taken with me.

Pavilion
Pavilion
Forum Contributor
Posts: 301
Joined: Thu Feb 23, 2012 6:51 am

Re: Field Validation Question

Post by Pavilion »

Following is the merged script. I am merely posting it here for purposes of documentation and closing out discussion around use of two files vs. one file. The following script works great. It is simpler and more stream-lined than 2 files. Celauran (or anyone else) if you notice unnecessary code within this script, please let me know. Also.... if the comments I've made within the script are wrong, please correct me. It is important to learn proper practices from the get-go.

Code: Select all

<?php
session_start();

// include database connection file, if connection doesn't work the include file will throw an error message
include '../####/db_files/db_connect.php';

// Error handling routine. 
$errors = array();
if (!empty($_POST)) // If NOT empty $_POST - exclamation point is "not" in php.
{
    $email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL);
    if (!$email)
    {
        $errors['email'] = "Not a valid email address.";
    }
    else
    {
        $email = mysql_real_escape_string($_POST['email']);
        $query = "SELECT COUNT(EmailAddress) FROM ContactTbl WHERE EmailAddress = '{$email}'"; // Checking for duplicate email address....
        list($email_count) = mysql_fetch_row(mysql_query($query));

        if ($email_count)
        {
            $errors['email'] = "That email address is already in use.";
        }
    }

    if (!$_POST['fname']) // If NOT $_POST - again exclamation point is "not" in php.
    {
        $errors['fname'] = "First name cannot be empty.";
    }
    if (!$_POST['lname'])
    {
        $errors['lname'] = "Last name cannot be empty.";
    }
	if (!$_POST['password'])
	{
        $errors['password'] = "Password cannot be empty.";
	}
}
	if ($_POST['password'] != $_POST['password2']) // This block of code checks for non-matching password submissions. If there is no match an error message is thrown. This "if" block is separate from the main "if" block checking for other empty fields, and invalid email addresses, because detecting non-matching password submissions has nothing to do with the function of the preceding "if" block.
	{
		$errors['password2'] = "Passwords do not match.";
	}

// Error handling is complete. Now declare variables from $_POST data and run insert statement.
if (!empty($_POST) && empty($errors))
{
    $fname = mysql_real_escape_string(trim($_POST['fname']));
    $lname = mysql_real_escape_string(trim($_POST['lname']));
    $password = mysql_real_escape_string(trim($_POST['password']));

    $query = "INSERT INTO ContactTbl (FName, LName, EmailAddress, Password) VALUES ('{$fname}', '{$lname}', '{$email}', '{$password}')"; //Notice order of operations, here. Variables are inserted into the statement in the same order as field names are listed.
	
	echo "You have successfully registered an account. Thank you.";
    mysql_query($query) or die(mysql_error());
}
session_destroy(); // Destroy sesson here, so error messages don't "carry over".
?>

<html>
    <head>
        <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
        <title>Contact Form</title>
        <style type="text/css">
            span.error
            {
                color: #F00;
                font-weight: bold;
            }
        </style>
    </head>
    <body>
        <form action="" method="post">
            <label for="fname">First Name</label>
            <input type="text" name="fname" />
            <?php if (isset($errors['fname'])): ?>
            <span class="error"><?php echo $errors['fname']; ?></span>
            <?php endif; // See an explanation of this coding at devnetwork.net forums - topic "Field Validation Question": http://forums.devnetwork.net/viewtopic.php?p=672372#p672372? />

            <label for="lname">Last Name</label>
            <input type="text" name="lname" />
            <?php if (isset($errors['lname'])): ?>
            <span class="error"><?php echo $errors['lname']; ?></span>
            <?php endif; ?><br />

            <label for="email">Email Address</label>
            <input type="email" name="email" />
            <?php if (isset($errors['email'])): ?>
            <span class="error"><?php echo $errors['email']; ?></span>
            <?php endif; ?><br />
			
			<label for="password">Password</label>
			<input type = "password" name="password" />
			<?php if (isset($errors['password'])): ?>
			<span class="error"><?php echo $errors['password'];?></span>
			<?php endif; ?><br />

			<label for="password2">Verify Password</label>
			<input type = "password" name="password2" />
			<?php if (isset($errors['password2'])): ?>
			<span class="error"><?php echo $errors['password2'];?></span>
			<?php endif; ?><br />

            <input type="submit" value="Submit" />
        </form>
    </body>
</html>
Once again... thank you for all of your help. I've still much to learn. As stated previously, my next goals are to figure out the confirmation email process and find a decent captcha.

Pavilion
User avatar
Celauran
Moderator
Posts: 6427
Joined: Tue Nov 09, 2010 2:39 pm
Location: Montreal, Canada

Re: Field Validation Question

Post by Celauran »

In the code as it currently stands, I don't see much need for sessions. You start and later destroy a session, but don't do anything with it in between.

More importantly, though, you're inserting plain text passwords into the database. This is a definite no-no. People generally choose poor passwords, this is known. They also generally use the same password all over the place. If your database is somehow compromised, you'll be giving up a list of email addresses and matching passwords. That the passwords will likely work for many of the victims' accounts is bad enough, but if it is the same password used on for their email account, it's basically game over for them. The attacker can then access their email, so any passwords that differ can't now be reset by following normal "forgot my password" procedures which send a reset link to the compromised email account. Sure this is a little fatalistic, a definite worst-case scenario, but the point is valid all the same.

That said, hash your passwords. I must have linked this a million times, but use bcrypt().
Pavilion
Forum Contributor
Posts: 301
Joined: Thu Feb 23, 2012 6:51 am

Re: Field Validation Question

Post by Pavilion »

Celauran wrote:In the code as it currently stands, I don't see much need for sessions. You start and later destroy a session, but don't do anything with it in between.
Celauran - I used sessions because, if there was an error message it would "hang around" too long. Once I used sessions the error messages started acting the way one would expect.
More importantly, though, you're inserting plain text passwords into the database. This is a definite no-no. People generally choose poor passwords, this is known. They also generally use the same password all over the place. If your database is somehow compromised, you'll be giving up a list of email addresses and matching passwords. That the passwords will likely work for many of the victims' accounts is bad enough, but if it is the same password used on for their email account, it's basically game over for them. The attacker can then access their email, so any passwords that differ can't now be reset by following normal "forgot my password" procedures which send a reset link to the compromised email account. Sure this is a little fatalistic, a definite worst-case scenario, but the point is valid all the same.

That said, hash your passwords. I must have linked this a million times, but use bcrypt().
I will surely read through your link and take your advice.

Pavilion
User avatar
Celauran
Moderator
Posts: 6427
Joined: Tue Nov 09, 2010 2:39 pm
Location: Montreal, Canada

Re: Field Validation Question

Post by Celauran »

Pavilion wrote:I used sessions because, if there was an error message it would "hang around" too long. Once I used sessions the error messages started acting the way one would expect.
The errors are never written to session data, so there's no risk of that. We only implemented that earlier as a way to send errors back from the processing page to the form. No longer needed. Now, the $errors array is declared at the top of the page, populated after form submission if errors are detected, and then displayed. The variable and everything it contains dies with the script.
Pavilion
Forum Contributor
Posts: 301
Joined: Thu Feb 23, 2012 6:51 am

Re: Field Validation Question

Post by Pavilion »

Celauran wrote:
Pavilion wrote:I used sessions because, if there was an error message it would "hang around" too long. Once I used sessions the error messages started acting the way one would expect.
The errors are never written to session data, so there's no risk of that. We only implemented that earlier as a way to send errors back from the processing page to the form. No longer needed. Now, the $errors array is declared at the top of the page, populated after form submission if errors are detected, and then displayed. The variable and everything it contains dies with the script.
OK... I'll take of out the sessions and see what happens.

Pavilion
Pavilion
Forum Contributor
Posts: 301
Joined: Thu Feb 23, 2012 6:51 am

Re: Field Validation Question

Post by Pavilion »

Celauran:

My hosting account is with GoDaddy. When testing system compatibility for Bcrypt - this is the returned message.
CRYPT_BLOWFISH is not available
Following is the syntax I used to determine compatibility:

Code: Select all

// checking for crypt blowfish

if (defined("CRYPT_BLOWFISH") && CRYPT_BLOWFISH) {
	echo "CRYPT_BLOWFISH is enabled!";
}
else {
	echo "CRYPT_BLOWFISH is not available";
}
Any advice is welcome.

Thanks Much:

Pavilion
User avatar
Celauran
Moderator
Posts: 6427
Joined: Tue Nov 09, 2010 2:39 pm
Location: Montreal, Canada

Re: Field Validation Question

Post by Celauran »

You may want to take a look at PHPass.
Post Reply