Foreword: There are two good reasons why email activation is a necessary for webmasters. First, it helps root out spam by requiring user interaction. It also creates a sense of trust, since we can build a certain amount of trust with a user who can confirm they are who they say they are. In this example you will need access to a database (MySQL is what we’ll use) with proper permissions.
We’ll start out creating the interface of the form. You will need to create two files: one file to hold the form, the next file to handle the verification process and interface with the database. It doesn’t necessarily matter what you name your files, but to stay uniform with our examples name the registration and verification files register.php and verify.php, respectively.
Below you will see register.php in action- in all its simplistic glory.
Our Registration Form – register.php
<html> <body> <form action="verify.php" method="post" name="register"> Username: <input type="text" name="username" /> Password: <input type="text" name="password" /> Email: <input type="text" name="email" /> <input type="submit" /> </form> </body> </html>
At this point the only things worth mentioning is that we are putting “verify.php” as the form action, and naming the form “register” with the name command. Go ahead and save this file and upload it to your hosting account- we’re done with this file for now.
Now let’s create a file named verify.php. We are using this file for two things. First, we use it to insert data into the database if everything seems to be hunky-dory. But we also use it to confirm the verification code we email the user, so we’ll need to make use of the “IF” selection structure to differentiate between the two processes.
So how do we know if the verify.php file should submit data to our database or verify the activation code a user provides? We’ll admit that when we said we were done with register.php, we lied. To properly determine if the user is submitting data or verifying a code, we need to add a hidden value on the registration form, as seen below:
Hidden Values For Our Registration Form – register.php
<html> <body> <form action="verify.php" method="post" name="register"> Username: <input type="text" name="username" /> Password: <input type="text" name="password" /> Email: <input type="text" name="email" /> <input type="hidden" name="form_submitted" value="1"/> <input type="submit" /> </form> </body> </html>
Now we can check to see if this value is set on our verify.php file with the following code:
Selection Structure – verify.php
if ($_POST['form_submitted'] == '1') { ## Form was submitted,the user is registering! } else{ ## No value found, user must be activating their account! }
With our form and selection structure in place, we need to go to our “backend” and create a database.
In our example we are creating a table named “users” with the fields “id, status, username, password, email, and activationkey” – we encourage you to use the same values for the sake of simplicity. In fact, you can just run the SQL query below and do just that:
SQL Query Code – Run Code to Create Table And Fields
CREATE TABLE IF NOT EXISTS `users` ( `id` int(11) NOT NULL auto_increment, `status` varchar(20) NOT NULL, `username` varchar(20) NOT NULL, `password` varchar(20) NOT NULL, `email` varchar(20) NOT NULL, `activationkey` varchar(100) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `username` (`username`), UNIQUE KEY `email` (`email`), UNIQUE KEY `activationkey` (`activationkey`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=9 ;
If all has gone well, your database should look something like the following (note if you aren’t using PHPMyAdmin and MySQL, you may see some differences):
Now that we have a good grasp on where we are going, we can go ahead and connect to our database. First we’ll need to arrange the correct connection statement. We will be using the mysql_connect and mysql_select_db functions to make the connection to our database.
Connecting To The Database – verify.php
mysql_connect("localhost", DATABASE, PASSWORD or ;die(mysql_error()); mysql_select_db("USER_TABLENAME ") or die(mysql_error());
Above we can see that the only thing we need to change is the database, password, and table name. Ideally the table name should be “users” as per our example. Your password and database name can be created via MySQL if you have the proper permissions. If you don’t, contact your web host to get a database configured.
So far your verify.php should look like this:
Project Thus Far – verify.php
<?php mysql_connect("localhost", "DATABASE", "PASSWORD") or die(mysql_error()); mysql_select_db("USER_TABLENAME") or die(mysql_error()); if ($_POST['form_submitted'] == '1') { } else { } ?>
Test the connection by uploading the file to your server and navigating to the file. If an error doesn’t present itself, it means you successfully connected to your database! (Even if you see a blank page) Now we can create a random key and answer all of the data into our database.
We will be using the mt_rand() function to create our random key. Below you’ll see that we concatenate the function five times in order to get a lengthy string.
Random Number Generator – verify.php
$activationKey = mt_rand() . mt_rand() . mt_rand() . mt_rand() . mt_rand();
Don’t get too excited to try it out yet, first let’s write the code to insert the value into our database.
Inserting Data Into A Database – verify.php
$sql="INSERT INTO users (username, password, email, activationkey, status) VALUES ('$_POST[username]', '$_POST[password]', '$_POST[email]', '$activationKey', 'verify')"; if (!mysql_query($sql)) { die('Error: ' . mysql_error()); }
Above you can see we are updating all of the rows with information from our registration field via the $_POST command. We are also including the $activationKey variable and inputting the word ‘verify’ into the status field. This is to keep track of who is verified and who isn’t. If someone isn’t verified yet, but has registered, we could easily have them request to resend the email instead of having to register again. Oh, technology!
So far the code should be as below:
Script Thus Far – verify.php
<?php mysql_connect("localhost", DATABASE, "PASSWORD") or die(mysql_error()); mysql_select_db("USER_TABLENAME ") or die(mysql_error()); if ($_POST['form_submitted'] == '1') { ##User is registering, insert data until ;we can activate it $activationKey = mt_rand() . mt_rand() . mt_rand() . mt_rand() . mt_rand(); $sql="INSERT INTO users (username, password, email, activationkey, status) VALUES ('$_POST[username]', '$_POST[password]', '$_POST[email]','$activationKey', 'verify')"; if (!mysql_query($sql)) { die('Error: ' . mysql_error()); } } else { } ?>
Sending an email with PHP is painlessly easy- we just have to supply a few values to an already-made function in PHP: the aptly named mail() command. In our example we are using four parameters to send the email: the recipient address, the subject of the email, the message, and our own return address.
Sending Mail With PHP – verify.php
echo "An email has been sent to $_POST[email] with an activation key. Please check your mail to complete registration."; ##Send activation Email $to = $_POST[email]; $subject = " YOURWEBSITE.com Registration"; $message = "Welcome to our website!\r\rYou, or someone using your email address, has completed registration at YOURWEBSITE.com. You can complete registration by clicking the following link:\rhttp://www.YOURWEBSITE.com/verify.php?$activationKey\r\rIf this is an error, ignore this email and you will be removed from our mailing list.\r\rRegards,\ YOURWEBSITE.com Team"; $headers = 'From: noreply@ YOURWEBSITE.com' . "\r\n" . 'Reply-To: noreply@ YOURWEBSITE.com' . "\r\n" . 'X-Mailer: PHP/' . phpversion(); mail($to, $subject, $message, $headers);
This should be fairly self-explanatory. Notice that we are using the \r command to force a return- this is to format the email so all the text isn’t on one line. If you wanted, you could even include HTML and images into the email. We would recommend you didn’t, however, as many mail platforms today either don’t support such features or mark most emails that contain them as spam.
We have arrived at the final part of this lesson: checking the verification code and allowing the user to either be registered or tell them they have entered the wrong code and to try again. In this section we will actually grab the current URL, take the query string, and then check our database to see if it matches a record. If it does, we will call the registrant a member and remove the key from our database. Otherwise, tough luck!
##User isn't registering, check verify code and change activation code to null, status to activated on success $queryString = $_SERVER['QUERY_STRING']; $query = "SELECT * FROM users"; $result = mysql_query($query) or die(mysql_error()); while($row = mysql_fetch_array($result)){ if ($queryString == $row["activationkey"]){ echo "Congratulations!" . $row["username"] . " is now the proud new owner of a YOURWEBSITE.com account."; $sql="UPDATE users SET activationkey = '', status='activated' WHERE (id = $row[id])"; if (!mysql_query($sql)) { die('Error: ' . mysql_error()); } } }
Above we are doing just as we stated. Pay special attention to the fact we are using the UPDATE command in SQL- not INSERT. Also note that we need the while loop to find the exact ID of the member to update- we don’t want to update everyone in our database! We do this by comparing the current record ID with one from the database- and voila! If a match is found, we can update it.
Finally, we need to add some security to our script. Read our SQL Injection Tutorial and add the updates below:
Final Result – verify.php
mysql_connect("localhost", DATABASE, "PASSWORD") or die(mysql_error()); mysql_select_db("USER_TABLENAME") or die(mysql_error()); if ($_POST['form_submitted'] == '1') { ##User is registering, insert data until we can activate it $activationKey = mt_rand() . mt_rand() . mt_rand() . mt_rand() . mt_rand(); $username = mysql_real_escape_string($_POST[username]); $password = mysql_real_escape_string($_POST[password]); $email = mysql_real_escape_string($_POST[email]); $sql="INSERT INTO users (username, password, email, activationkey, status) VALUES ('$username', '$password', '$email', '$activationKey', 'verify')"; if (!mysql_query($sql)) { die('Error: ' . mysql_error()); } echo "An email has been sent to $_POST[email] with an activation key. Please check your mail to complete registration."; ##Send activation Email $to = $_POST[email]; $subject = " YOURWEBSITE.com Registration"; $message = "Welcome to our website!\r\rYou, or someone using your email address, has completed registration at YOURWEBSITE.com. You can complete registration by clicking the following link:\rhttp://www.YOURWEBSITE.com/verify.php?$activationKey\r\rIf this is an error, ignore this email and you will be removed from our mailing list.\r\rRegards,\ YOURWEBSITE.com Team"; $headers = 'From: noreply@ YOURWEBSITE.com' . "\r\n" . 'Reply-To: noreply@ YOURWEBSITE.com' . "\r\n" . 'X-Mailer: PHP/' . phpversion(); mail($to, $subject, $message, $headers); } else { ##User isn't registering, check verify code and change activation code to null, status to activated on success $queryString = $_SERVER['QUERY_STRING']; $query = "SELECT * FROM users"; $result = mysql_query($query) or die(mysql_error()); while($row = mysql_fetch_array($result)){ if ($queryString == $row["activationkey"]){ echo "Congratulations!" . $row["username"] . " is now the proud new owner of an YOURWEBSITE.com account."; $sql="UPDATE users SET activationkey = '', status='activated' WHERE (id = $row[id])"; if (!mysql_query($sql)) { die('Error: ' . mysql_error()); } } } }
So where should you take it from here? Obviously we haven’t included any error checking for input data. What if the user misspelled his or her password? We should probably put another password field in, and check to see if the passwords match. Additionally, we should mask the content in the password field to ensure security.
We might also add a CAPTCHA to prevent the mail server from getting abused by spam bots- something your host would probably appreciate. We could also simplify matters by using functions and cleaning up code.
There are many ways to improve- but be sure to check out our scripts and tutorials section for more information, because we’ve covered such topics like this in the past.
Wonderful tutorial! I just have one question is there a way to set a time limit for activating an account so that if they do not activate the account in so many days that it will automatically delete the account from the database to keep it nice and clean from people who never activate their accounts?
What I have done is create a page that lists all accounts that have not been activated. You can then select to either activate them if you are the admin, or you can delete them as well. You need to have a switch to decipher between activated and non-activated. Overall it works extremely well and fast too.
Thank you man! Now waiting user login tutorial, how to accept approved users and ignore those who want to join without verification mail. And maybe you have something with imagre verification to prevent from computer submitting.
this is wonderful code for validation of email. i was searching last 2 hours and ultimately i found this. thnx buddy!.
A nice tutorial…I like it. while implementing i changed steps little bit.Firstly, I take Email of user and send him or her a mail including activation key. if he or she verifies email provided then only i provide a page for registration.
Nice script but when I tried it I found a problem after one record I received error duplicate entry key 4 so I think the problem is here activation wont work unless you have only one user because of this line $query = “SELECT * FROM users”; so do we need a WHERE clause?? may I ask you for a help?? Thanks in advance.
A nice tutorial…I like it. while implementing i changed steps little bit.i was searching last 2 hours and ultimately i found this. thnx
Just include a timestamp in the database and test for status v. timestamp.