Creating a Simple PHP and MySQL-Based Login System
From TPC! Web Development
About this Tutorial
In this tutorial, we will create a basic MySQL-driven login system using PHP as the primary language. As time passes, we will elaborate on this tutorial and create a full-fledged login system with a multitude of features.
Files
- /login.php - Front-facing login screen
- /index.php - Password-protected page
- /css/login.css - CSS file for login screen
- /includes/config.inc.php - Database configuration file
- /includes/function.inc.php - Core functions
- /includes/login.inc.php - Login script
- /includes/logout.inc.php - Logout script
Step 1 - Creating the Users Table & Adding a User
The following MySQL query will create the users table we will need to create the login system:
CREATE TABLE `tpc_tutorials`.`users` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY , `username` VARCHAR( 20 ) NOT NULL , `password` VARCHAR( 32 ) NOT NULL , UNIQUE ( `username` ) ) ENGINE = MYISAM
- id - Each user is assigned a unique ID, AUTO_INCREMENT ensures that this automatically increases with each user that is added.
- username - Each username must be unique and no greater than 20 characters.
- password - Because we will be using MD5 encryption, which produces unique strings with a length of 32 characters, we have allowed this field a maximum of 32 characters.
Next, we will add a user to the users table:
INSERT INTO `tpc_tutorials`.`users` ( `id` , `username` , `password` ) VALUES ( NULL , 'admin', MD5( 'password' ) );
The MySQL statement above creates a user with admin as the username, and password as the password. The MD5 command will encrypt the password in a 32-character string. If all is working properly, you should end up with 5f4dcc3b5aa765d61d8327deb882cf99 in the password field.
Step 2 - Create the Database Configuration File (includes/config.inc.php)
In this step, we will create a configuration file that stores our MySQL database connection settings. Creating a separate file for database settings helps if you have to change your MySQL username, password, server, or database. Otherwise, you may end up having to make the same change over and over again, which can be quite time-consuming. (I learned this the hard way!)
<?php /** * MySQL Database Configuration * * @file /includes/config.inc.php * @note Replace the settings below with those for your MySQL database. */ define('DB_HOSTNAME', 'database_hostname'); define('DB_USERNAME', 'database_username'); define('DB_PASSWORD', 'database_password'); define('DB_DATABASE', 'database_name'); ?>
Step 3 - Create the Functions (includes/functions.inc.php)
The functions file includes those functions frequently used, and consolidating these help save time and reduce code clutter. The key concepts illustrated in this part of the tutorial are:
- Functions & function commenting
- Use of header() for redirection
<?php /** * Crucial Functions for Application * * @package tpc_tutorials * @file /includes/functions.inc.php */ /** * Redirects to specified page * * @param string $page Page to redirect user to * @return void */ function redirect($page) { header('Location: ' . $page); exit(); } /** * Check login status * * @return boolean Login status */ function check_login_status() { // If $_SESSION['logged_in'] is set, return the status if (isset($_SESSION['logged_in'])) { return $_SESSION['logged_in']; } return false; }
Step 4 - Create the Login Script (includes/login.inc.php)
The script we create during this step will be executed after we submit a username and password via the login screen. Several key concepts will be illustrated in this step:
- Sanitizing data (making sure data is safe for database)
- Simple MySQL queries using the object-oriented MySQLi extension
- Including an external PHP file
- Use of $_SESSION variables
<?php // Include required MySQL configuration file and functions require_once('config.inc.php'); require_once('functions.inc.php'); // Start session session_start(); // Check if user is already logged in if ($_SESSION['logged_in'] == true) { // If user is already logged in, redirect to main page redirect('../index.php'); } else { // Make sure that user submitted a username/password and username only consists of alphanumeric chars if ( (!isset($_POST['username'])) || (!isset($_POST['password'])) OR (!ctype_alnum($_POST['username'])) ) { redirect('../login.php'); } // Connect to database $mysqli = @new mysqli(DB_HOSTNAME, DB_USERNAME, DB_PASSWORD, DB_DATABASE); // Check connection if (mysqli_connect_errno()) { printf("Unable to connect to database: %s", mysqli_connect_error()); exit(); } // Escape any unsafe characters before querying database $username = $mysqli->real_escape_string($_POST['username']); $password = $mysqli->real_escape_string($_POST['password']); // Construct SQL statement for query & execute $sql = "SELECT * FROM users WHERE username = '" . $username . "' AND password = '" . md5($password) . "'"; $result = $mysqli->query($sql); // If one row is returned, username and password are valid if (is_object($result) && $result->num_rows == 1) { // Set session variable for login status to true $_SESSION['logged_in'] = true; redirect('../index.php'); } else { // If number of rows returned is not one, redirect back to login screen redirect('../login.php'); } } ?>
Step 5 - Create the Log Out Script (includes/logout.inc.php)
There are two new PHP features introduced in this script: unset() and session_destroy().
- unset() - Unsets specified variable
- session_destroy() - Destroys all data registered to a session
<?php // Start session session_start(); // Include required functions file require_once('functions.inc.php'); // If not logged in, redirect to login screen // If logged in, unset session variable and display logged-out message if (check_login_status() == false) { // Redirect to redirect('login.php'); } else { // Kill session variables unset($_SESSION['logged_in']); unset($_SESSION['username']); // Destroy session session_destroy(); } ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-type" content="text/html;charset=utf-8" /> <title>Creating a Simple PHP and MySQL-Based Login System - dev.thatspoppycock.com</title> </head> <body> <h1>Logged Out</h1> <p>You have successfully logged out. Back to <a href="../login.php">login</a> screen.</p> </body> </html>
Step 6 - Create the Login Page (login.php)
The following HTML page is one example of how you can style and layout your login screen. The CSS will be created in the next step, which can be edited to suit your needs.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-type" content="text/html;charset=utf-8" /> <title>Creating a Simple PHP and MySQL-Based Login System - dev.thatspoppycock.com</title> <link rel="stylesheet" type="text/css" href="css/login.css" /> </head> <body> <form id="login-form" method="post" action="includes/login.inc.php"> <fieldset> <legend>Login to Web Site</legend> <p>Please enter your username and password to access the administrator's panel</p> <label for="username"> <input type="text" name="username" id="username" />Username: </label> <label for="password"> <input type="password" name="password" id="password" />Password: </label> <label for="submit"> <input type="submit" name="submit" id="submit" value="Login" /> </label> </fieldset> </form> </body> </html>
Step 7 - Creating the Login Screen CSS File (css/login.css)
Create a new directory called css, and save the following in a file called login.css.
body { font-family: 'Trebuchet MS', Verdana, Arial, sans-serif; font-size: 10pt; } #login-form { width: 300px; margin: 0 auto; } #login-form fieldset { padding: 10px; } #login-form legend { font-weight: bold; font-size: 9pt; } #login-form label { display: block; height: 2em; background-color: #e7e7e7; padding: 10px 10px 0; } #login-form input { margin-right: 20px; border: 1px solid #999; float: right; clear: right; background: #ccc; } #login-form input:focus, #login-form input-hover { border: 1px solid #333; }
Step 8 - Creating the Admin Page (index.php)
The first instruction we pass is session_start(), which allows us to use the $_SESSION variable to access information. After that, we bring our library of functions so we can use the check_login_status() and redirect() functions. The if statement in the code block redirects the user back to the login screen if he/she is not logged in.
<?php // Start session session_start(); // Include required functions file require_once('includes/functions.inc.php'); // Check login status... if not logged in, redirect to login screen if (check_login_status() == false) { redirect('login.php'); } ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-type" content="text/html;charset=utf-8" /> <title>Creating a Simple PHP and MySQL-Based Login System - dev.thatspoppycock.com</title> </head> <body> <h1>Administration Panel</h1> <p>You are currently logged in. You may log out using the button below.</p> <p><a href="includes/logout.inc.php">Log Out</a></p> </body> </html>


Apr 30 2009 12:02 am
another great tutorial thanks.
Jun 17 2009 4:44 pm
very nice, clear, simple and teaching a lot of staff
in the way it has to be done. the code is very readable.
Thank You.Jun 26 2009 7:19 am
Awesome tutorial!
I've just started a new project and thought that it would be the perfect opportunity to learn PHP, your page has been a great starting point for my login system :)
Thanks!Jul 05 2009 2:24 am
G'day,
This seems like a great intro, I'm just having a little trouble getting it going.
I have the main 'index.php' file called by another web page that is acting as a sort of application menu setup. When I click on the link to start this new app, I get the following message - "Warning: Cannot modify header information - headers already sent by (output started at /var/www/app/includes/functions.inc.php:36) in /var/www/app/includes/functions.inc.php on line 17"
Line 17 is the 'header' statement.
Any ideas on what could be wrong here.
Thanks for any help
..PaulJul 16 2009 7:52 am
Thanks for this tutorial. Is all I was looking for.
Jul 29 2009 5:51 am
Hey,
Awesome tutorial, followed it to the letter but I have an issue with the login.inc.php. When i enter my username and password the script executes but doesent properly re-direct to index.php, it just displays a blank white page, no errors or anything.
any ideas? Im very new to php and thereofre will most likey have missed somethin out somewhere, but i've double checked my scripts against the tutorila and cant find any descrpancysAug 19 2009 3:34 am
logout.inc.php:
Why are you unsetting 'username' session.
unset($_SESSION['username']);
It has never been set.Aug 19 2009 1:32 pm
This solution would allow a hacker to break in to pages behind the login simply by adding the variable "logged in" to their message. A secure solution would put some uniquely generated certificate in the cookie (or somewhere else). The value of the cookie would be something a hacker could not guess or replay, and it must be something the server could use to verify the identity of the person.
Aug 19 2009 10:29 pm
awesome tutorial thank you!
Sep 05 2009 2:00 pm
Unable to connect to database: Host '216.108.239.38' is not allowed to connect to this MySQL server
HELP ME PLEASE It says that, and i used:
admin password
What is wrong?Sep 05 2009 11:40 pm
It sounds like you are trying to connect to a MySQL server remotely. You have to make sure that the server you are trying to connect to MySQL from is in the allowed remote hosts. I'll need more on your server setup to be of more help. Are you using cPanel, Plesk, or something else?