RSS

Basic Register System

Wed, Jan 20, 2010

PHP & MySql

In this tutorial we’ll be creating a register system in which people can create their own account. It’s a basic register system which uses some mysql functions to insert data into the database (create the account), loops and some PHP functions to handle the POST variables. We’ll start creating our register page with a form in which the user can fill in the info for his or her account.

File: Register.php

<form method="POST" action="<?php echo $_SERVER['PHP_SELF']; ?>">

... form felds ...

</form>

We start by creating the form itself. The attributes we set are method and action. Method is used to define how the data (text filled in the form fields) should be transferred. We use the POST method, which will store all data filled in by the user into $_POST variables. The action is set to the page where it should go to when the form is submitted. We set it to $_SERVER['PHP_SELF'], which is equal to the current file. So after the user completes filling in our form fields and submits the form, it will put all filled in data into $_POST variables and send it to itself (go to the same page).

Let’s add some form fields to the form, which the user needs to fill in to complete the registration.

<form method="POST" action="<?php echo $_SERVER['PHP_SELF']; ?>">

*Username:
 <br />

*Password  :
 <br />

*Repeat Password: 
 <br />

*Email:
 <br />


</form>

We simply added 4 fields using basic HTML input tags and a submit button to submit the form. These four fields need to be filled in by the user in order to create his/her account. They may not be left empty: the username, password and email. We also created a “repeat password” field, which we use to verify the user filled in password. The name we give each input field is important because for each input field, a POST variable will be created once the user submits the form. The POST variable created for a certain field is $_POST['field_name'] and will contain the value the user gave to that field (filled in for that field). In this way all values of the fields will be submitted using POST variables. We will use these variables to check if the user filled in all fields (if they aren’t empty) and if the form has been submitted at all.

To actually create the account we’ll be storing the filled in values for the fields, into a database. Let’s create a database called “test” and a table called “accounts” which contains 4 fields ( equal to the amount of fields that are filled in for the form plus one ID field which is unique for each member ( password and repeat password should contain one and the same value so are of course just stored in one field: password ) ). If you are not sure how to do this you could also import the SQL code :

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
CREATE DATABASE 'test' DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci;
USE 'test';
CREATE TABLE IF NOT EXISTS 'accounts' (
  'id' int(250) NOT NULL AUTO_INCREMENT,
  'username' varchar(20) NOT NULL,
  'password' varchar(20) NOT NULL,
  'email' varchar(50) NOT NULL,
  PRIMARY KEY ('id')
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

Now we’ll create a loop to check if the user has already submitted the form. Which is the case when all fields data have been stored into $_POST variables. In other words: if the $_POST variables exist – the form has been submitted. This doesn’t mean all fields have been filled in though, because the $_POST variables could also be empty, but they are created ( as the user submitted the form).

<?php

If ( ... the form has been submitted ... ) {

    ... check if all fields have been filled in correctly ...

}else{ //form has not been submitted yet

    ... show the form ...

}

?>

This is how our loop looks like. Now we can already fill in our form which we just created and to check if the form has been submitted we just check if $_POST variable exists:

<?php
If ( $_POST  ) {

    ... check if all fields have been filled in correctly - create account if valid ...

}else{ //form has not been submitted yet

?>

<form method="POST" action="<?php echo $_SERVER['PHP_SELF']; ?>">

*Username:
 <br />

*Password  :
 <br />

*Repeat Password: 
 <br />

*Email:
 <p>


</form>

<?php

}

?>

Only thing last is to check all fields and create the account if valid. As mentioned before, once the form has been submitted, all field values have been stored into $_POST['field_name']. So to check if all fields have been filled in, we just need to check if all $_POST variables aren’t empty. To do this we are going to use a foreach loop to make it easier. We could also just check all $_POST variables like: $_POST['username'] and $_POST['password'], etc.. But this is an inefficient way to do it, as when you add a new form field, you would need to add it to the loop as well ( check that field too ). Beside that it just can be done much easier and faster than checking all fields manually. The foreach loop will check all fields and values the same way. Let’s just have alook at the loop code:

foreach ( $_POST as $key => $value ) {

    if ( empty($value) )

        $errors .= "Field '".$key."' has to be filled in. <br /> ";

    }else{

        ... check if filled in values are valid ...

    }

}

Ok, let’s go through this code. What it basicly does is check all sub-variables of the array $_POST ( which are all fields ) and store the name of them in $key and the value of them in $value. As for each field a sub-variable for the array $_POST has been created, it will check each field. $key will contain the name of the field and $value the value ( filled in by the user ). Then we use an if loop to check if the value of the field is empty: we use the function empty to do this. If it’s empty, we’ll add text to a variable called $errors. This variable we use to store all errors into if any. This way we can also check if there are any errors at all by checking if the variable $errors contains anything: if not, the user filled in all fields correctly and we can create the account. Otherwise it should show the errors ( echo $errors ).

Now there’s one more part of the if loop that needs to be done: the part where it checks if the values filled in are actually valid. This part runs when the $value was not empty. We’ll use a function preg_match for this. What we basicly do is check if it contains the characters that are allowed ( which are basicly: numbers, spaces and alphabetical characters ). The function works like this:

preg_match("/[...pattern that needs to be matched...]/", $value_to_check)

In our case the pattern is equal to all numbers, spaces and alphabetical characters as mentioned above. The value to check is the filled in value of the field, which is stored in $value as as well mentioned above. This makes us end up with the following code:

        If ( !preg_match("/[0-9A-Za-z -_]/", $value) )
            $errors .= "<p> Field '".$key."' has been given an invalid value. </p>";

All numbers are 0-9, all capital alphabetical characters are A-Z and all normal alphabetical characters are a-z, and we also allow the – and _ symbols to be used. Now we check if the value filled in for the current field ( stored in $value ) does NOT match this pattern . Which is the case when it contains any other symbols/characters than the ones given in the pattern. We use the ! symbol for that, which means simply: NOT. In that case we add an error to the $error variable ( the field is not filled in correctly, using inappropriate characters ).

Let’s put it all together.

<?php

If ( $_POST  ) {

foreach ( $_POST as $key => $value ) {

        if ( empty($value) )

            $errors .= "<p> Field '".$key."' has to be filled in. </p>";

        }else{

            If ( !preg_match("/[0-9A-Za-z -_]/", $value) )
                $errors .= "<p> Field '".$key."' has been given an invalid value. </p>";

        }

}

    ...  check if the passwords ( normal and repeated ) matched ...

    ... check if username/email does not already exist ...

    ...  check if there were any errors with the filled in fields ...

}else{ //form has not been submitted yet

?>

<form method="POST" action="<?php echo $_SERVER['PHP_SELF']; ?>">

*Username:
 <br />

*Password  :
 <br />

*Repeat Password: 
 <br />

*Email:
 <p>


</form>

<?php

}

?>

There’s one field that needs to be checked in a different way: the ‘password_rep’ field. Which needs to be equal to the password field. We’ll use another if loop for that (already put into the code above):

        If( $_POST['password_rep'] != $_POST['password'])
            $errors .= "<p> Passwords don't match! </p>";

A simple condition checks whether they are not equal to eachother (!=). In that case, an error will be added.

Now there’s a last thing that needs to be checked. We’re going to check if there isn’t already an account on the given username or email. We’ll use a simple mysql SELECT query to do this:

        $check_account = mysql_query("SELECT id
                                                                    FROM accounts
                                                                    WHERE username = '".$_POST['username']."' OR email = '".$_POST['email']."' ");

We select the field ‘id’ from the table ‘accounts’ (we could select any field) from a row where the username or email is equal to what the user filled in as username/email. To make it more secure we can use the mysql_real_escape_string function that escapes all possible harming characters out of the strings.

        $check_account = mysql_query("SELECT id
                                                                     FROM accounts
                                                                     WHERE username = '".mysql_real_escape_string($_POST['username'])."' OR email = '".mysql_real_escape_string($_POST['email'])."' ");

Next, instead of retrieving the rows/results ( as we aren’t sure if there is any row like this already ) we’ll check if the query selected any rows at all. In other words: we’ll check if there is already an account with this username or email as this is the only thing we need to check with this query. We’ll use the function mysql_num_rows to do this.

        $check_account = mysql_query("SELECT id
                                                                    FROM accounts
                                                                    WHERE username = '".mysql_real_escape_string($_POST['username'])."' OR email = '".mysql_real_escape_string($_POST['email'])."' ");

        $check_account = mysql_num_rows($check_account);

$check_account now contains a number of the rows that have the same username or email as the user filled in for his account to register. So if $check_account contains a number greater than 0, this means there’s already 1 or more accounts with this username or email. In that case an error should be added that the username or email already exists for an account.

        $check_account = mysql_query("SELECT id
                                                                    FROM accounts
                                                                    WHERE username = '".mysql_real_escape_string($_POST['username'])."' OR email = '".mysql_real_escape_string($_POST['email'])."' ");

        $check_account = mysql_num_rows($check_account);

        If($check_account > 0)
            $errors .= "<p> An account with the same username or email already exists. </p>";

Now we need to create a code to check if there were any errors: in other words if $errors contains text. We’ll again use the empty function. If $errors is empty, we can create the account. Otherwise we show the errors.

Now we checked all possible errors for the user filled in data for his/her account to be created. So let’s put it all together.

<?php

If ( $_POST  ) {

foreach ( $_POST as $key => $value ) {

        if ( empty($value) )

            $errors .= "<p> Field '".$key."' has to be filled in. </p>";

        }else{

            If ( !preg_match("/[0-9A-Za-z -_]/", $value) )
                $errors .= "<p> Field '".$key."' has been given an invalid value. </p>";

        }

}
        If( $_POST['password_rep'] != $_POST['password'])
            $errors .= "<p> Passwords don't match! </p>";

        $check_account = mysql_query("SELECT id FROM accounts WHERE username = '".mysql_real_escape_string($_POST['username'])."' OR email = '".mysql_real_escape_string($_POST['email'])."' ");

        $check_account = mysql_num_rows($check_account);

        If($check_account > 0)
            $errors .= "<p> An account with the same username or email already exists. </p>";

    ...  check if there were any errors with the filled in fields ...

}else{ //form has not been submitted yet

?>

<form method="POST" action="<?php echo $_SERVER['PHP_SELF']; ?>">

*Username:
 <br />

*Password  :
 <br />

*Repeat Password: 
 <br />

*Email:
 <p>


</form>

<?php

}

?>
If ( empty($errors) OR !isset($errors) ) {

    ... create account ...

}else{

    ... show errors ...

}

Showing the errors is not such a big deal, we just echo the variable $errors which contains all errors. Creating the account isn’t such a big deal either. We’ll be using a few mysql functions & queries. Which we use to insert rows into the database ( create the account ). First we’ll need to connect to the host and database. We’ll use the functions mysql_connect and mysql_select_database.

mysql_connect("host", "user", "pass");
mysql_select_db("database");

We’ll now use a basic mysql_query function to INSERT the values into the database.

mysql_query( ... query ... );

In our case the query is to INSERT all values into the table ‘accounts’.

$query = mysql_query("INSERT INTO accounts(username, password, email)VALUES('".$_POST['username']."', '".$_POST['password']."', '".$_POST['email']."')");

That’s how the query looks like. I think it isn’t that hard so will explain it shortly: we use INSERT INTO to insert data into a table, in our case ‘account’s . Then we need to define which fields we want to insert data into, and put them between brackets after the table: username, password, email in this case. Also we need to give the VALUES for each field, which are stored in $_POST['field_name']. Though, to be sure there won’t be any SQL injections possible, we will still use the mysql_real_escape_string function to handle all filled in values so that they can’t harm the database with any bad codes. Even though we already checked the values, you should never just directly insert user filled in data to the database.

$query = mysql_query("INSERT INTO accounts(username, password, email)VALUES('".mysql_real_escape_string($_POST['username'])."', '".mysql_real_escape_string($_POST['password'])."', '".mysql_real_escape_string($_POST['email'])."')");

Now we need to check if the query was successfully:

If($query) {

    echo "Success! Account created!";

}else{

    echo "There was an error creating the account. Please try again or contact the web administrator";

}

We just use a basic loop to check if the $query variable, which executes the mysql query, was executed successfully.

Now we put it all together!

File: Register.php

<?php

If ( $_POST  ) {

foreach ( $_POST as $key => $value ) {

        if ( empty($value) )

            $errors .= "<p> Field '".$key."' has to be filled in. </p>";

        }else{

            If ( !preg_match("/[0-9A-Za-z -_]/", $value) )
                $errors .= "<p> Field '".$key."' has been given an invalid value. </p>";

        }

    }

        If( $_POST['password_rep'] != $_POST['password'])
            $errors .= "<p> Passwords don't match! </p>";

        $check_account = mysql_query("SELECT id FROM accounts WHERE username = '".mysql_real_escape_string($_POST['username'])."' OR email = '".mysql_real_escape_string($_POST['email'])."' ");

        $check_account = mysql_num_rows($check_account);

        If($check_account > 0)
            $errors .= "<p> An account with the same username or email already exists. </p>";

If ( empty($errors) OR !isset($errors) ) {

mysql_connect(host, user, pass);
mysql_select_db(database);

$query = mysql_query("INSERT INTO accounts(username, password, email)VALUES('".mysql_real_escape_string($_POST['username'])."', '".mysql_real_escape_string($_POST['password'])."', '".mysql_real_escape_string($_POST['email'])."')");

If($query) {

    echo "Success! Account created!";

}else{

    echo "There was an error creating the account. Please try again or contact the web administrator";

}

}else{

    echo $errors;

}

}else{ //form has not been submitted yet

?>

<form method="POST" action="<?php echo $_SERVER['PHP_SELF']; ?>">

*Username:
 <br />

*Password  :
 <br />

*Repeat Password: 
 <br />

*Email:
 <p>


</form>

<?php

}

?>

And we’ve got our register system in ONE file!

Note: In queries you might have seen a lot of quotes and double quotes. We use ‘”. and .”‘ to separate an array ( like $_POST[] ) from the rest of the query.

Cheers,
Admin.