Hello, Hostmatrix! I've decided to write my first "real" tutorial instead of a snippet this time for all of you to enjoy and hopefully learn from; hopefully you will learn something, even if you are experienced with PHP. So I will be teaching you how to make a user system, being that it is a popular topic for people to want to learn about. But not just any user system! A
secure user system!
First, what you will need is some PHP hosting that supports MySQL databases. You can check out
our hosting packages if you meet the requirements, as our hosting supports all of the features that will be used in this tutorial.
Now that we have all of this out of the way, we will now start the tutorial. Each "heading" will just be
bolded so that you can distinguish the parts from each other. I will also put filenames in
italics. Finally, things that you definitley need to change in the code are bolded in the code boxes. Simple and effective, right? Note that this tutorial will be showing through cPanel, so it may be different with set up with your provider if you don't use HM, though it shouldn't be hard to figure out!
Setting up the Databases
This tutorial will have a lot of MySQL involved, so we need to make sure we can set up a database and keep consistant with it. So first we will need to set up a database. Open cPanel and click on the "MySQL Databases" button. Scroll down until you see the following:
There, enter "usys", which will become "cpanelusername_usys" once you click "Create Database". Then, you will need to create a MySQL user on your account in this form (after creating the database):
Create the username and password you wish your database to have and click submit. Keep these safe, as you don't want malicious users figuring out your database information and dropping your tables! Now, all we have to do is add the MySQL user to the database and we will be ready to use it. Scroll to the following form:
We want to keep it checked to "ALL" because we want to be able to use all of the functions that MySQL has to offer with this database
Well, now we are ready to actually put something into the database, instead of having a useless piece of data stored in your account! Open phpMyAdmin by going to the link near the bottom of the MySQL page and click on the SQL icon in the sidebar. We are going to write some code so that MySQL will create the database the way we want! In the code box, we will put:
Code:
CREATE TABLE `cpanelusername_usys`.`users` (
`id` INT( 10 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`username` VARCHAR( 16 ) NOT NULL ,
`password` VARCHAR( 32 ) NOT NULL ,
`email` VARCHAR( 255 ) NOT NULL
) ENGINE = MYISAM
The first line tells MySQL that you want to create the table 'users' on the database 'cpanelusername_usys' (replace cpanelusername with your cPanel username). The second line creates an integer field 10 characters long, which increments automatically with each new value. The other fields it creates are strings of various lengths for storing things such as usernames, email addresses and more. The final line just tells which engine to use and closes the SQL query.
A Note on Security
Throughout the years, people have found ways to manipulate data sent from browsers to servers, often using methods known as "SQL Injection", which basically allows them to enter malicious stuff into the form and cause databases to lose information or even fail altogether! Therefore, it is important that we create a way to secure the strings passed without too much manipulation. There are many ways to do this:
PHP Code:
addslashes($string);
stripslashes($string);
The addslashes() function adds slashes to escape quotations, apostrophes, and other special characters, which is a simple way to protect strings.
PHP Code:
mysql_real_escape_string($string);
If you are connected to MySQL, you can use this function, which will escape a lot of stuff too as to help secure the strings. Personally, I just create a function that uses a couple of the methods:
PHP Code:
function cleanString($string){
htmlentities(mysql_real_escape_string($string));
return $string;
}
As I have come to understand, htmlentities() will return a code (like the code for ♥ ) of each character, which will, when shown anywhere, show up as the text. However, it doesn't execute as malicious code when it passes through, making this another reliable way to clean the strings. This function will be used throughout the tutorial.
Handling the Sessions
A simple way that can be used to handle sessions consistantly throughout pages is to use an included file containing functions and session checks. This will cut down on coding a LOT, as you won't be rewriting over and over and over again.
handler.php
PHP Code:
<?php
session_start();
mysql_connect("localhost", "[b]cpanelusername[/b]_[b]sqlusername[/b]", "[b]sqlpassword[/b]");
mysql_select_db("[b]cpanelusername[/b]_usys");
function cleanString($string){
htmlentities(mysql_real_escape_string($string));
return $string;
}
if(!$_SESSION['username'] || !$_SESSION['password']){
$loggedIn = False;
} else {
$loggedIn = True;
}
?>
This file uses a fairly simple yet effective way to check if you are logged in. Once you include this file, you can also use the $loggedIn variable to check if somebody is logged in from whatever page includes it.
The cleanString function was explained in the last section. The other part of the code uses the session variables array. The exclamation before means "not", and the double-bar means "or", so the code is basically checking: "If the username session is not set or the password session is not set, then the user is not logged in, otherwise the user is logged in".
Registering New Users
Now that we have a place to store all of the user information in a secure way, and a way to check if they have already logged in, it is time to let them register! However you want to, create a form with the following fields (with the name attribute identified as such in the parenthesis):
- Username (username)
- Password (password)
- Confirm Password (cpassword)
- Email (email)
- Confirm Email (cemail)
Make sure the form action is set to
process_registration.php, which we will now create in the same directory. Also make sure that the form method is "POST", as this is how we will work with the variables sent from the form.
The first thing we want to do is get the data sent through the form from the POST array. So the first thing we will do is start our script with this.
process_registration.php
PHP Code:
<?php
require_once 'handler.php';
$username = cleanString($_POST['username']);
$password = $_POST['password'];
$cpassword = $_POST['cpassword'];
$email = cleanString($_POST['email']);
$cemail = cleanString($_POST['cemail']);
$errors = array();
The above code just starts the PHP script with the first line, then it make sure that the
handler.php file loaded. By using the require_once() function for this, if it doesn't load then the script won't run! As well, it won't be included if you put the require_once() in there again for the same file. All of the following lines get the data from the POST array of the form, with each of the parameters from the form (which we defined with the "name" attribute!), while using our cleanString function to make sure it is an okay input. Finally, we add an array to hold all of the errors that the form encounters. Now we are going to run some checks on each of these to make sure everything is nice and spiffy before we go and add their details to our database.
First we will check to see if the username is already in use:
PHP Code:
$sql = mysql_query("SELECT * FROM users WHERE username = '$username'");
if(mysql_num_rows($sql) != 0){
$errors[] = "That username is already in use.";
}
That will run the MySQL query in the $sql variable, and then will check the number of entries in the database with the parameters "username = '$username'". Basically, if there is not 0 entries, the username has been used (remember that "!=" means "is not equal to"!). Now we will check the passwords to see if they match. While we are at it, we will check to see if the email addresses match, as the code is very VERY similar
PHP Code:
if($password != $cpassword){
$errors[] = "Your passwords do not match.";
}
if($email != $cemail){
$errors[] = "Your email addresses do not match.";
}
The code is basically the same for all of them, but uses different pairs of variables. All each of the blocks does is check if the two variables are the same. Nothing too major here. Next we will check to see if the password is long enough.
PHP Code:
if(strlen($password) > 16 || strlen($password) < 6){
$errors[] = "Your password must be between 6 and 16 characters. All characters are allowed.";
}
What is done here is having the script get the length of the password. If the password is longer than 16 characters or shorter than 6 characters, the user will need to go back and try again. Finally, we will check if the email address is a valid one! To do this, we will use regular expressions.
PHP Code:
if(!preg_match("/^[a-z0-9]+([_\\.-][a-z0-9]+)*@([a-z0-9]+([\.-][a-z0-9]+)*)+\\.[a-z]{2,}$/i", $email)){
$errors[] = "You need to enter a valid e-mail address.";
}
I'm not going to go in-depth on regular expressions as I am not good at them, but this will check to see if the email address is valid. If you want to know more about RegEx there are many good guides online.
Now that we have gone through all of the possible errors (though you could add more if you like), we are going to either output the errors (if there are errors), or add the user to our database. First we will output errors if there are any.
PHP Code:
if(count($errors) > 0){
echo 'There were some problems with submitting your registration:<br /><ul>';
foreach($errors as $error){
echo '<li>' . $error . '</li>';
}
echo '</ul>';
}
First, it tells the user that there were problems with the form. The "foreach" loop is a loop designed for arrays, which we use here to loop through the error array to display the errors in a list. Finally, we just end the list. Now, if there were no errors, we would be adding the user to the database.
PHP Code:
else{
mysql_query("INSERT INTO [b]cpanelusername[/b]_usys.users (username, password, email) VALUES ('$username', '" . md5($password) . "', '$email')");
echo 'You have successfully registered. You can now log in.';
}
?>
That makes a query to MySQL to add the username, password, and email values to the users table in our database. You may wonder why the id isn't there? Well because that is an "auto_increment" field, as it is added it will increase by one and create a unique ID for each user! This also finishes up the registration script. Time to let the users log in!
Creating the Log In
Now that we have our user registered, they need to be able to use the details they created to log in! This script is a lot more simple than the last one, so it won't be as hard to work with. Plus, most everything used in this section has been taught in the last section! That will also make this section shorter. First, we have to, of course, make a form so that our users can log in! This form needs:
- Username (username)
- Password (password)
Yes, just those two fields! Make sure they are named as such for simplicity in following the tutorial. Since we have a form made, point it to send the action to
process_login.php, method POST.
process_login.php
PHP Code:
<?php
require_once 'handler.php';
$username = cleanString($_POST['username']);
$password = md5($_POST['password']);
This should look familiar from the last section, it is how we add in everything we need to work with. However, we use a small alteration this time around. As we get the password variable, we are going to hash it using md5, as that is how it is stored in the database. Next we will check the details against those stored in the database.
PHP Code:
if(empty($username) || empty($password)){
echo 'You must enter a username and password!';
}
This will check for the fields to be empty. If they are, then oh no! They need to go back and fill it out!
PHP Code:
else{
$sql = mysql_query("SELECT * FROM users WHERE username='$username'");
if(mysql_num_rows($sql) < 1){
echo 'That username does not exist.';
}
That will check if the username exists by checking the table for rows with that username. If it doesn't find a single one, then that username must not exist! Now we will check their password:
PHP Code:
else{
$sql2 = mysql_query("SELECT * FROM users WHERE username='$username' AND password='$password'");
if(mysql_num_rows($sql2) < 1){
echo 'Your password is incorrect.';
}
That uses a similar manner to check for the password, however it also checks the username. The else is there because if the username is incorrect, we don't want to check a password of an invalid username! Finally, now that we have a few simple checks, we can log the user in!
PHP Code:
else{
$_SESSION['username'] = $username;
$_SESSION['password'] = $password;
}
}
}
?>
Since we are using sessions, we will use the session array variables for username and password to store if they are logged in. This will keep the session open as long as they keep their browser open, otherwise it is likely that they can get logged out. That wraps up the login! Wow, wasn't that simple?
Logging Out
Now that the user has the ability to log in, they should be able to log out. This will probably be one of the most simple features to implement.
logout.php
PHP Code:
<?php
require_once 'handler.php';
unset($_SESSION['username']);
unset($_SESSION['password']);
echo 'You have successfully logged out. Thank you!';
?>
All that this script does is empty the session variables, which, as the handler would take it, send a "logged out user" signal.
Making a Page Members-Only
This is a feature that a lot of people want, because it is the main reason they make a membership system. The way the handler.php file works allows you to do this in a very simple manner.
PHP Code:
<?php
require_once 'handler.php';
if($loggedIn == False){
header("Location: [b]http://yoursite.hostmatrix.org/login.php[/b]");
die();
}
?>
That snippet should go on the top of any page you want to be members-only. What it does is check the loggedIn variable from the handler.php file, which checks the session variables for being logged in. If it determines the user is not logged in, it will create a redirect using the header function. This allows you to change header information, and using "Location: " will allow you to redirect the page to the login page.
Note that if you want to use this, the extension on the file has to be/must be changed to
.php, as .htm, .html, and similar will not read the PHP.
Closing Words
Thank you for following this tutorial. I've spent around 3 hours or so working on it, and that is with the code coming mostly from memory, so there may be typos. Also, if there are any features you aren't sure about, or want some help, just post. I am trying to come up with more sections/pages to walkthrough, or even new tutorial ideas, so if you have any ideas, please let me know!
Also, I will be submitting this tutorial to various tutorial sites (such as Pixel2Life, Tutorialized) to help boost HM traffic, so if you know of any more, feel free to let me know where else to submit it to!