Page 4 of 5

Re: Field Validation Question

Posted: Sat Mar 03, 2012 1:10 pm
by califdon
I'm sure the password storage frameworks suggested by Celauran are excellent, high security solutions, but if you are having trouble implementing them, I would suggest that for ordinary applications you could code it yourself with only a few lines of PHP code, which is all I have ever used, but I haven't needed especially tight security in my applications.

The only functionality that you need to learn is the several built-in PHP hash functions, such as crypt() or sha1(), etc. The underlying concept is this:
Never store the plain text password!
Instead, when establishing a password, store the encrypted (hashed) version, whether it is in a database, a session variable, etc.
When validating a user, they supply the password, you encrypt (hash) it with the same method, and compare that with the stored encrypted password.

That's all there is to it. That's not as secure as using "salts" in the encryption, or many other techniques, but for most applications, it is secure enough. The one thing to absolutely avoid is storing the raw password, as Celauran said.

Re: Field Validation Question

Posted: Sat Mar 03, 2012 2:13 pm
by Pavilion
califdon wrote:I'm sure the password storage frameworks suggested by Celauran are excellent, high security solutions, but if you are having trouble implementing them, I would suggest that for ordinary applications you could code it yourself with only a few lines of PHP code, which is all I have ever used, but I haven't needed especially tight security in my applications.

The only functionality that you need to learn is the several built-in PHP hash functions, such as crypt() or sha1(), etc. The underlying concept is this:
Never store the plain text password!
Instead, when establishing a password, store the encrypted (hashed) version, whether it is in a database, a session variable, etc.
When validating a user, they supply the password, you encrypt (hash) it with the same method, and compare that with the stored encrypted password.

That's all there is to it. That's not as secure as using "salts" in the encryption, or many other techniques, but for most applications, it is secure enough. The one thing to absolutely avoid is storing the raw password, as Celauran said.
califdon - Thank you for this input. For the most part, the applications I plan on building won't be so important that I'll need advanced encryption. But.. (and there is always a but) ... I am working very hard to learn php for one client's application. Their "critical mission" database is something I've built and maintained over the past 15 years. We will be porting data from the php/mySQL application to their existing database (and back again). This client is large, well known in the area, and the data they manage requires a higher level of security.

So... whether it is enjoyable (or not), I've got to figure this one out. (sigh)

I've spent some time today pouring over the links Celauran provided. I've gained some insight, but have a long way to go... (sigh again.... )

Pavilion

Re: Field Validation Question

Posted: Sat Mar 03, 2012 3:01 pm
by Pavilion
Pavilion wrote:So... whether it is enjoyable (or not), I've got to figure this one out. (sigh)

I've spent some time today pouring over the links Celauran provided. I've gained some insight, but have a long way to go... (sigh again.... )

Pavilion
WHOOT!!! WHOOT!!! I just figured out how to hash a password. :D Thanks Celauran - it's much appreciated.

Now... I am trying to get a confirmation email up and going. I've found some files (and a topic right on this board) that should be of help. ...

I'm sure questions will arise - and I'll be back soon. :wink:

Re: Field Validation Question

Posted: Sun Mar 04, 2012 8:30 am
by Pavilion
OK - I am REALLY Stumped here. This morning I've been working on adding a confirmation email to my register.php. All was going well. I even got one email to "send". Then it all went to pot. Now - for some reason, the data isn't writing to the table, and no email is being sent. All I did was add a confirmation echo statement, after the email, then the database insertion and email stopped working.

Following is my code for register.php

Code: Select all

<?php
// including PasswordHash file for purposes of hashing passwords.
require '../PasswordHash.php';

// 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(); //Declare an Array to store any error message. As php process the following "if" statement, true results are added to the $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)) // if NOT "!" empty $_POST and is empty $errors then proceed.
{
    $fname = mysql_real_escape_string(trim($_POST['fname']));
    $lname = mysql_real_escape_string(trim($_POST['lname']));
    $password = mysql_real_escape_string(trim($_POST['password']));
	$firstcontact = date("Y-m-d");
	
	// Now hash the $password before inserting into ContactTbl
	$hasher = new PasswordHash($hash_cost_log2, $hash_portable);
	$hash = $hasher->HashPassword($password);
	if (strlen($hash) < 20)
	fail('Failed to hash new password');
	unset($hasher);
	
	// Create a unique  activation code:
	$activation = md5($website . $timestamp . rand(100000, 999999));
	
	// Insert data into table. Notice order of operations, here. Variables are inserted into the statement in the same order as field names are listed.
	$query = "INSERT INTO ContactTbl (FName, LName, EmailAddress, Password, 1stContact, Activation) VALUES ('{$fname}', '{$lname}', '{$email}', '{$hash}', '{$firstcontact}', '{$activation}')";
	
	$result = mysql_query("SELECT * FROM ContactTbl");
	echo $result;
	
	// Send the confirmation email
		$subject = '<span class="posthilit">Email</span> <span class="posthilit">confirmation</span>';
        $message = 'Hi!Thanks <span class="posthilit">for</span> creating an account on our site. Click the link below to confirm your <span class="posthilit">email</span> address:';
        $message .= "\r\nUsername: ";
        $message .= $email;
        $message .= "\r\nPassword: ";
        $message .= $password;
        $message .= "\r\n";
        $message .= "\r\nhttp://" . $website . '/activate.php?email=' . urlencode($Email) . "&key=$activation";
        $message .= "\r\n\r\nThis is an automated message - please do not reply";
		$header = 'From:'.EMAIL;
        $header .= "MIME-Version: 1.0" . "\r\n";
        $header .= "Content-Type: text/plain; charset=utf-8" . "\r\n";
        $header .= "Content-Transfer-Encoding: 8bit" . "\r\n";
        $header .= "X-Mailer: PHP v" . phpversion();
        mail($newemail, $subject, $message, $header);
			
	 // Finish the page:
	echo 'Thank you for registering! A confirmation email has been sent to ' . $email . ' Please click on the Activation Link to Activate your account.';
}
?>

<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>
In the way of problem solving, I did the following:
  1. Tested all error handling - it all works
  2. All the following code chunks echoed back just fine
    • $fname
    • $lname
    • $password
    • firstcontact
    • hash
    • activation
    • result - echos back with 'Resource id #7" - I assume this means there is a database connection and it is functioning
  3. my fields for storing $hash and $activation are large enough to store the hash strings. Yesterday, I succeeded in sending several registrations to the database with a successful $hash. This morning I succeeded in writing a record to the database with a successful $activation before everything just quit working.
  4. The confirmation message AFTER the data insertion and email blocks does work.
Any insight from others would be greatly appreciated.

Thanks Much - Pavilion

Re: Field Validation Question

Posted: Sun Mar 04, 2012 10:15 am
by Celauran
Pavilion wrote:Now... I am trying to get a confirmation email up and going. I've found some files (and a topic right on this board) that should be of help. ...
Yeah... no. That topic, I suspect, will be very much the opposite of help. Stay away.

I have added comments to your file below. I used /** comment here **/ syntax to avoid confusion with existing comments.

Code: Select all

<?php
// including PasswordHash file for purposes of hashing passwords.
require '../PasswordHash.php';

// 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(); //Declare an Array to store any error message. As php process the following "if" statement, true results are added to the $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)) // if NOT "!" empty $_POST and is empty $errors then proceed.
{
    $fname = mysql_real_escape_string(trim($_POST['fname']));
    $lname = mysql_real_escape_string(trim($_POST['lname']));
    $password = mysql_real_escape_string(trim($_POST['password']));
    $firstcontact = date("Y-m-d");

    // Now hash the $password before inserting into ContactTbl
    /** I can't see the included file; have $hash_cost_log2 and $hash_portable been defined? **/
    $hasher = new PasswordHash($hash_cost_log2, $hash_portable);
    $hash = $hasher->HashPassword($password);
    if (strlen($hash) < 20)
        fail('Failed to hash new password');
    unset($hasher);

    // Create a unique  activation code:
    /** Are $website and $timestamp defined somewhere? **/
    $activation = md5($website . $timestamp . rand(100000, 999999));

    // Insert data into table. Notice order of operations, here. Variables are inserted into the statement in the same order as field names are listed.
    $query = "INSERT INTO ContactTbl (FName, LName, EmailAddress, Password, 1stContact, Activation) VALUES ('{$fname}', '{$lname}', '{$email}', '{$hash}', '{$firstcontact}', '{$activation}')";
    /** Where's the mysql_query call? You're not ever running the above query.
        Also, have you defined a column in the table to determine whether or not
        the account is active? I see one for the activation code... **/
    
    /** What's this about? **/
    $result = mysql_query("SELECT * FROM ContactTbl");
    echo $result;

    /** No. Just... no. Don't send HTML email. Don't send someone's password by email! 
        You've also got a bunch of undefined variables below. **/
    // Send the confirmation email
    $subject = '<span class="posthilit">Email</span> <span class="posthilit">confirmation</span>';
    $message = 'Hi!Thanks <span class="posthilit">for</span> creating an account on our site. Click the link below to confirm your <span class="posthilit">email</span> address:';
    $message .= "\r\nUsername: ";
    $message .= $email;
    $message .= "\r\nPassword: ";
    $message .= $password;
    $message .= "\r\n";
    $message .= "\r\nhttp://" . $website . '/activate.php?email=' . urlencode($Email) . "&key=$activation";
    $message .= "\r\n\r\nThis is an automated message - please do not reply";
    $header = 'From:' . EMAIL;
    $header .= "MIME-Version: 1.0" . "\r\n";
    $header .= "Content-Type: text/plain; charset=utf-8" . "\r\n";
    $header .= "Content-Transfer-Encoding: 8bit" . "\r\n";
    $header .= "X-Mailer: PHP v" . phpversion();
    mail($newemail, $subject, $message, $header);

    // Finish the page:
    echo 'Thank you for registering! A confirmation email has been sent to ' . $email . ' Please click on the Activation Link to Activate your account.';
}
?>

<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; ?>

            <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>

Re: Field Validation Question

Posted: Sun Mar 04, 2012 11:23 am
by Pavilion
Celauran wrote:
Pavilion wrote:Now... I am trying to get a confirmation email up and going. I've found some files (and a topic right on this board) that should be of help. ...
Yeah... no. That topic, I suspect, will be very much the opposite of help. Stay away.
(wry smile) OK - we'll do.
I have added comments to your file below. I used /** comment here **/ syntax to avoid confusion with existing comments.
Following are answers to your questions:

Code: Select all

    /** I can't see the included file; have $hash_cost_log2 and $hash_portable been defined? **/
Actually the include file is on line 3. With classical databases my practice has always been to put other code references at the beginning of the file (whenever possible). That way I know where to look for them.

Code: Select all

    /** Are $website and $timestamp defined somewhere? **/
    $activation = md5($website . $timestamp . rand(100000, 999999));
Nope - you got me there Celauran. I saw them in some sample code and thought they were pre-defined variables. That is my mistake. I should have echoed them, before using them.

Code: Select all

    /** Where's the mysql_query call? You're not ever running the above query.
        Also, have you defined a column in the table to determine whether or not
        the account is active? I see one for the activation code... **/
THANK YOU!!! I must have unintentionally deleted this line when adding new code for a confirmation email. Once I re-inserted the mysql query call (from a previous version of this .php file) the data insertion worked.

Code: Select all

    /** What's this about? **/
    $result = mysql_query("SELECT * FROM ContactTbl");
    echo $result;
It's about nothing - except testing. I'm operating at a "baby steps" level here. And when things went wrong I was trying to determine if there was communication with the database. This code is removed from the file now.

Code: Select all

    /** No. Just... no. Don't send HTML email. Don't send someone's password by email!
OK -- this way of sending email is not appropriate. Do you have an example of "best practice" email confirmation? If you do, it would really be appreciated.

Thanks so much for all your help - Pavilion

Re: Field Validation Question

Posted: Sun Mar 04, 2012 11:33 am
by Celauran
Pavilion wrote:

Code: Select all

    /** I can't see the included file; have $hash_cost_log2 and $hash_portable been defined? **/
Actually the include file is on line 3. With classical databases my practice has always been to put other code references at the beginning of the file (whenever possible). That way I know where to look for them.
That's good practice; I do the same. I meant that I literally could not see the included file (ie. its contents), so had no way of knowing if those variables had been defined within.

For sending mail, your baby steps approach is ideal here. For now, all you really need in the body is the activation link. Have you written a page to handle the activation links (ie. when someone clicks on one)?

Re: Field Validation Question

Posted: Sun Mar 04, 2012 4:28 pm
by Pavilion
Celauran wrote:For sending mail, your baby steps approach is ideal here. For now, all you really need in the body is the activation link. Have you written a page to handle the activation links (ie. when someone clicks on one)?
No... actually if you know of any good tutorials-examples-exercises in confirmation emails and activation pages, it would be very helpful. Found this exercise. But... having a few different examples gives me a broader perspective.

Thanks Much - Pavilion

Re: Field Validation Question

Posted: Sun Mar 04, 2012 8:57 pm
by Celauran
I don't know of any good tutorials but, then, I doubt you really need one. Break the problem down into its individual steps and I'm sure you'll find it's quite easy.
  • User visits a URL containing his username and activation code
  • You grab said variables from URL
  • Query database for a match
  • Update database if match is found (set user to active)
  • Present login form or link to login page

Re: Field Validation Question

Posted: Sun Mar 04, 2012 9:21 pm
by Pavilion
Celauran wrote:I don't know of any good tutorials but, then, I doubt you really need one. Break the problem down into its individual steps and I'm sure you'll find it's quite easy.
  • User visits a URL containing his username and activation code
  • You grab said variables from URL
  • Query database for a match
  • Update database if match is found (set user to active)
  • Present login form or link to login page
Hello Celauran - thank you. You're right - it's a step-by-step process. This evening I've managed to put most of the puzzle pieces together. Following is my activate.php code:

Code: Select all

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

if (isset($_GET['email']) && preg_match('/^([a-zA-Z0-9])+([a-zA-Z0-9\._-])*@([a-zA-Z0-9_-])+([a-zA-Z0-9\._-]+)+$/',
 $_GET['email'])) {
 $email = $_GET['email'];
}
if (isset($_GET['key']) && (strlen($_GET['key']) == 32))
 //The Activation key will always be 32 since it is MD5 Hash
 {
 $key = $_GET['key'];
}

if (isset($email) && isset($key)) {

 // Update the database to set the "activation" field to null

	$query_activate_account = "UPDATE ContactTbl SET Activation = NULL, Active = '1' WHERE(EmailAddress ='$email' AND Activation='$key')LIMIT 1";
	$result_activate_account = mysql_query($link, $query_activate_account);
 
 // Print a customized message:
 if (mysql_affected_rows($link) == 1) //if update query was successfull
 {
 echo '<div>Your account is now active. You may now <a href="login.php">Log in</a></div>';

 } else {
 echo '<div>Oops !Your account could not be activated. Please recheck the link or contact the system administrator.</div>';

 }

 mysql_close($link);

} else {
 echo '<div>An Error Occured. I have no idea where, but an error did occur.</div>';
}
?>
I'm getting an error message for line 20 - it follows:
Warning: mysql_query(): supplied argument is not a valid MySQL-Link resource in /home/content/38/7901938/html/schedule/activate.php on line 20
Line 20 follows:

Code: Select all

$result_activate_account = mysql_query($link, $query_activate_account);
$link is my mysql_connect variable. It is defined in my database connection file - included on line 1 of activate.php. I've included this same connection file in register.php. It has worked to write data to the table in register.php. So... I can't figure out why it is not acceptable in this context.

Any insight you can offer would be greatly appreciated.
_________________

OH!! one last thing - I've thought of this before, but always forget to ask. Should I be closing my database connection at the end of every php file? And, specifically, should I include this line at the end of register.php?

Code: Select all

mysql_close($link);
Thanks Much - Pavilion

P.S. Following is applicable code in register.php, just in case you need to reference script used to create and send an email:

Code: Select all

// Create a unique  activation code:
$timestamp = date(timestamp);
$activation = md5($timestamp . rand(100000, 999999));

Code: Select all

//Send Confirmation email. Following are the variables for the email 
$sendto = $email; // this is the email address collected from the form 
$subject = "Email Confirmation"; // Subject 
$message = "Thank you for registering. To activate your account, please click this link: http://www.wearethedemocracy.com/schedule/activate.php?email=" . urlencode($email) . "&key=$activation";
$header = "From: auto-confirm@yourdomain.com\r\n"; 
$header .= "Reply-to: you@yourdomain.com\r\n"; 

// Collect variables from above and insert into the mail() function. 
mail($sendto, $subject, $message, $header);

Re: Field Validation Question

Posted: Sun Mar 04, 2012 9:24 pm
by Celauran
mysql_query

You've got your parameters in the wrong order.

There's certainly no harm in closing your database connection when you're done with it. I never bother because it will be closed anyway when the script finishes executing.

Re: Field Validation Question

Posted: Sun Mar 04, 2012 9:36 pm
by Pavilion
Celauran wrote:mysql_query

You've got your parameters in the wrong order.
THANK YOU!!! It works like a charm. My active field is set to True (0) and Activation is set to null.
There's certainly no harm in closing your database connection when you're done with it. I never bother because it will be closed anyway when the script finishes executing.
So not closing the database connection - does NOT affect security of the database?

Thanks Again Celauran. Now I just have to work on the login page.

Pavilion

Re: Field Validation Question

Posted: Wed Mar 07, 2012 8:17 am
by Pavilion
Well... the registration process is working smoothly. A new user can:
  1. register
  2. receive an email - with confirmation link
  3. click the confirmation link and validate themselves as a user. The active field is set to true.
  4. I've not started the login page yet, because I wanted to do some cleanup.
My first round of cleanup was to change the name of the table from ContactTbl to UserTbl. The name change is complete at MySQL level and in all applicable script files. All processes continue to function smoothly.

My second round of clean up was to create a css format file and store it in a format directory. That way I can use the same formatting across different php/html files without constantly rewriting the css basics.

My third round of clean up was to format the form in register.php (and that brings me back here with a question).

All my formatting words great - except for one thing. The message a user receives, after successfully registering, displays at the top of the page. It displays above the header image and above the background image.

How do I get that message to display in-line - on the page itself? All input elements are in a table. How can I get that message to display in a box to the right of the table? Do I need to use a variable and then put the variable in the form?

Following is the most recent code in register.php

Code: Select all

<?php
// including PasswordHash file for purposes of hashing passwords.
require '../PasswordHash.php';

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

// include css styles format file
include '../schedule/formats/formats.css';

// Error handling routine. 
$errors = array(); //Declare an Array to store any error message. As php process the following "if" statement, true results are added to the $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 UserTbl 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)) // if NOT "!" empty $_POST and is empty $errors then proceed.
{
    $fname = mysql_real_escape_string(trim($_POST['fname']));
    $lname = mysql_real_escape_string(trim($_POST['lname']));
    $password = mysql_real_escape_string(trim($_POST['password']));
	$firstcontact = date("Y-m-d");
	
	// Now hash the $password before inserting into UserTbl
	$hasher = new PasswordHash($hash_cost_log2, $hash_portable);
	$hash = $hasher->HashPassword($password);
	if (strlen($hash) < 20)
	fail('Failed to hash new password');
	unset($hasher);
	
	// Create a unique  activation code:
	$timestamp = date(timestamp);
	$activation = md5($timestamp . rand(100000, 999999));
	
	// Insert data into table. Notice order of operations, here. Variables are inserted into the statement in the same order as field names are listed.
	$query = "INSERT INTO UserTbl (FName, LName, EmailAddress, Password, 1stContact, Activation) VALUES ('{$fname}', '{$lname}', '{$email}', '{$hash}', '{$firstcontact}', '{$activation}')";

	mysql_query($query) or die(mysql_error()); // this is the mysql_query call. No data will be inserted into the table without this call.
	
	//Send Confirmation email. Following are the variables for the email 
		$sendto = $email; // this is the email address collected from the form 
		$subject = "Email Confirmation"; // Subject 
		$message = "Thank you for registering. To activate your account, please click this link: http://www.wearethedemocracy.com/schedule/activate.php?email=" . urlencode($email) . "&key=$activation";
		$header = "From: auto-confirm@yourdomain.com\r\n"; 
		$header .= "Reply-to: you@yourdomain.com\r\n"; 
	// Collect variables from above and insert into the mail() function. 
		mail($sendto, $subject, $message, $header);
	
	echo 'Thank you for registering! A confirmation email has been sent to ' . $email . ' Please click on the Activation Link to Activate your account.';
}
?>
<!DOCTYPE html>
<html>
<div class="background">
<div class="header"><head>
<a><IMG SRC="/schedule/images/logo.jpg" ALT="" WIDTH=98% HEIGHT=175"></a>
	<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
	<title>Contact Form</title>
</head></div>
<form action="" method="post">
<div class="borderbx" style="width=36%";>
	<h1 style="text-align:left; padding-left:50px;"><i>Register Here .... </i></h1>
</div>
	<table align="left" style = "width=35%;">
		<tr>
		<td align="right">
		<label for="fname">First Name</label>
		</td>
		<td align="left">
			<input tabindex="1" 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?
		</td>
		<td align="right">
			<label for="password">Password</label>
		</td>
		<td align="left">
			<input tabindex="4" type = "password" name="password" />
			<?php if (isset($errors['password'])): ?>
			<span class="error"><?php echo $errors['password'];?></span>
			<?php endif; ?><br />
		</td>
		</tr>
		<tr>
		<td align="right">
			<label for="lname">Last Name</label>
		</td>
		<td align="left">
            <input tabindex="2" type="text" name="lname" />
            <?php if (isset($errors['lname'])): ?>
            <span class="error"><?php echo $errors['lname']; ?></span>
            <?php endif; ?><br />
		</td>
		<td align="right">
			<label for="password2">Verify Password</label>		
		</td>
		<td align="left">
			<input tabindex="5" type = "password" name="password2" />
			<?php if (isset($errors['password2'])): ?>
			<span class="error"><?php echo $errors['password2'];?></span>
			<?php endif; ?><br />
		</td>
		</tr>
		<tr>
		<td align="right">
            <label for="email">Email Address</label>
		</td>
		<td align="left">
            <input tabindex="3" type="email" name="email" />
            <?php if (isset($errors['email'])): ?>
            <span class="error"><?php echo $errors['email']; ?></span>
            <?php endif; ?><br />
		</td>
		<td align="right">
            <input style="font-weight:bold;" tabindex="6"type="submit" value="Submit" />
		</td>
		</tr>
	</table>
</form>
</div>
</html>
Thanks again for your help. I know formatting is NOT php - but my struggle here is to get a php message into an html form. I appreciate any advice offered.

Pavilion

Re: Field Validation Question

Posted: Wed Mar 07, 2012 8:44 am
by Celauran
A few problems I noticed:
Your HTML is malformed. You have your <head> inside a <div>, you have no <body>, and you're using inline styling in places.
This is outside the if (!empty($_POST)) block:

Code: Select all

if ($_POST['password'] != $_POST['password2'])
Once I fixed these minor errors, everything appeared to be working fine. Errors displayed next to their inputs, though this made the table expand and look weird.

Re: Field Validation Question

Posted: Wed Mar 07, 2012 12:19 pm
by Pavilion
Hello Celauran:

I placed the

Code: Select all

if ($_POST['password'] != $_POST['password2'])
inside an else statement with

Code: Select all

 if (!$_POST['lname'])
. It works as it should.

I put a <body> in the form and took out the offending <div>:

The error messages do fall into line. That isn't the problem. The problem is the confirmation message, if registration is successful. The confirmation message appears ABOVE the HEADER. Isn't there a way to get it to fall in line, maybe next to the table, or underneath the table?

Thanks Much: Pavilion