4 Steps Simple User Login System With PHP MySQL (Free Download!)

Welcome to a tutorial on how to create a simple user login system with PHP and MYSQL. So you have just started a project and want to secure the administration panel? Maybe create a “members only” section?

A simple user login system consists of the following essential components:

  • A user database table to keep the emails and passwords.
  • PHP user library to manage the users.
  • The login page itself.
  • Finally, protecting all the pages.

This guide will walk you through an example of how to do these exactly – Read on to find out!

ⓘ I have included a zip file with all the source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.

 

 

TABLE OF CONTENTS

Download & Notes Login System Useful Bits & Links
Tutorial Video The End

 

DOWNLOAD & NOTES

Firstly, here is the download link to the example code as promised.

 

QUICK NOTES

  • Create a database and import 1-users.sql.
  • Change the database settings to your own in 2-user-lib.php.
  • Access 3-login.php in your web browser, and that’s all. The Dummy user account is “jon@doe.com” and the password is “123456”.
If you spot a bug, feel free to comment below. I try to answer short questions too, but it is one person versus the entire world… If you need answers urgently, please check out my list of websites to get help with programming.

 

 

EXAMPLE CODE DOWNLOAD

Click here to download the source code in a zip file – I have released it under the MIT License, so feel free to build on top of it if you want to.

 

 

LOGIN SYSTEM WITH PHP MYSQL

All right, let us now get into the details of building a login system with PHP and MYSQL.

 

STEP 1) CREATE A USER DATABASE TABLE

1-users.sql
CREATE TABLE `users` (
  `user_id` int(11) NOT NULL,
  `user_name` varchar(255) NOT NULL,
  `user_email` varchar(255) NOT NULL,
  `user_password` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

ALTER TABLE `users`
  ADD PRIMARY KEY (`user_id`),
  ADD UNIQUE KEY `user_email` (`user_email`);
 
ALTER TABLE `users`
  MODIFY `user_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2;

INSERT INTO `users` (`user_id`, `user_name`, `user_email`, `user_password`) VALUES
  (1, 'Jon Doe', 'jon@doe.com', '$2y$10$eGdnkD1EcFdLmPtm0eqQ8OqjjRo6NWrXKDmbieFPKHmRUTmz7iYzi');
Field Description
user_id Primary key, and auto-increment.
user_name The user’s name.
user_email The user’s email address. Unique field to prevent multiple registrations.
user_password The password. This should be encrypted.

Yep, it’s as simple as that. Feel free to add more fields as required.

 

 

STEP 2) PHP USER CLASS

2-user-lib.php
<?php
class Users {
  // (A) CONSTRUCTOR - CONNECT TO DATABASE
  private $pdo = null;
  private $stmt = null;
  public $error = null;
  function __construct () {
    try {
      $this->pdo = new PDO(
        "mysql:host=".DB_HOST.";dbname=".DB_NAME.";charset=".DB_CHARSET,
        DB_USER, DB_PASSWORD, [
          PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
          PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
      ]);
    } catch (Exception $ex) { exit($ex->getMessage()); }
  }

  // (B) DESTRUCTOR - CLOSE DATABASE CONNECTION
  function __destruct () {
    if ($this->stmt !== null) { $this->stmt = null; }
    if ($this->pdo !== null) { $this->pdo = null; }
  }

  // (C) RUN SQL QUERY
  // $sql : sql to run
  // $data : data to bind
  function query ($sql, $data=null) {
    $this->stmt = $this->pdo->prepare($sql);
    $this->stmt->execute($data);
  }
  // (D) GET USER
  // $id : user id or email
  function get ($id) {
    $this->query(sprintf("SELECT * FROM `users` WHERE `user_%s`=?",
      is_numeric($id) ? "id" : "email"
    ), [$id]);
    return $this->stmt->fetch();
  }

  // (E) VERIFY EMAIL PASSWORD - SESSION MUST BE STARTED!
  // $email : user email
  // $password : user password
  function login ($email, $password) {
    // (E1) ALREADY SIGNED IN
    if (isset($_SESSION["user"])) { return true; }
    
    // (E2) GET USER
    $user = $this->get($email);
    if (!is_array($user)) { return false; }

    // (E3) VERIFY PASSWORD + REGISTER SESSION
    if (password_verify($password, $user["user_password"])) {
      $_SESSION["user"] = [];
      foreach ($user as $k=>$v) { if ($k!="user_password") { $_SESSION["user"][$k] = $v; }}
      return true;
    }
    return false;
  }
  
  // (F) SAVE USER
  // $name : user name
  // $email : user email
  // $pass : user password
  // $id : user id (for updating only)
  function save ($name, $email, $pass, $id=null) {
    // (F1) ADD/UPDATE SQL
    if ($id===null) {
      $sql = "INSERT INTO `users` (`user_name`, `user_email`, `user_password`) VALUES (?,?,?)";
      $data = [$name, $email, password_hash($pass, PASSWORD_DEFAULT)];
    } else {
      $sql = "UPDATE `users` SET `user_name`=?, `user_email`=?, `user_password`=? WHERE `user_id`=?";
      $data = [$name, $email, password_hash($pass, PASSWORD_DEFAULT), $id];
    }
 
    // (F2) PROCESS SAVE
    try {
      $this->stmt = $this->pdo->prepare($sql);
      $this->stmt->execute($data);
      return true;
    } catch (Exception $ex) {
      $this->error = $ex->getMessage();
      return false;
    }
  }
}

// (G) DATABASE SETTINGS - CHANGE TO YOUR OWN!
define("DB_HOST", "localhost");
define("DB_NAME", "test");
define("DB_CHARSET", "utf8");
define("DB_USER", "root");
define("DB_PASSWORD", "");

// (H) CREATE USER OBJECT
$USR = new Users();

Yikes! This looks massive, but keep calm and study closely.

  • (A & B) When $USR = new Users() is created, the constructor will connect to the database. The destructor closes the connection.
  • (C) query() A support function to run an SQL query.
  • (D To F) There are only 3 user functions!
    • get() Self-explanatory. Get the user with the given email address or user ID.
    • login() Process login, do checks and stuff.
    • save() To add or update a user. For example, $USR->save("Jane Doe", "jane@doe.com", "123456");
  • (G & H) Database settings and the user object. Doh.

 

 

STEP 3) USER LOGIN PAGE

3-login.php
<?php
// (A) PROCESS LOGIN ON SUBMIT
session_start();
if (isset($_POST["email"])) {
  require "2-user-lib.php";
  $USR->login($_POST["email"], $_POST["password"]);
}
 
// (B) REDIRECT USER IF SIGNED IN
if (isset($_SESSION["user"])) {
  header("Location: 4-index.php");
  exit();
}
 
// (C) SHOW LOGIN FORM OTHERWISE ?>
<!-- (C1) ERROR MESSAGES (IF ANY) -->
<?php
if (isset($_POST["email"])) {
  echo "<div id='notify'>Invalid user/password</div>";
}
?>
 
<!-- (C2) LOGIN FORM -->
<form id="login" method="post">
  <h2>MEMBER LOGIN</h2>
  <input type="email" name="email" placeholder="Email" required>
  <input type="password" name="password" placeholder="Password" required>
  <input type="submit" value="Sign In">
</form>
  1. When the login form is submitted, we use the user library to process the login.
  2. If the user is signed in, redirect to the home page.
  3. The login form itself.

 

 

STEP 4) SECURE ALL THE PAGES

4-protect.php
<?php
// (A) "LISTEN" FOR LOGOUT
session_start();
if (isset($_POST["logout"])) {
  unset($_SESSION["user"]);
}
 
// (B) REDIRECT TO LOGIN PAGE IF NOT SIGNED IN
if (!isset($_SESSION["user"])) {
  header("Location: 3-login.php");
  exit();
}

Yes, just include this snippet at the top of all the pages that you want to secure. This should be self-explanatory again – Redirect all users who are not signed in to the login page.

 

 

EXTRA) HOW TO LOGOUT

4-index.php
<?php
require "4-protect.php";
?>

Congrats! You have signed in.
<form method="post">
  <input type="submit" name="logout" value="Logout"/>
</form>

Captain Obvious to the rescue! Notice that if (isset($_POST["logout"])) { unset($_SESSION["user"]); } in 4-protect.php? Simply create a form that will POST a log out to itself.

 

USEFUL BITS & LINKS

That’s it for the tutorial, and here are some stuff and links that might be useful to you.

 

USE HTTPS!

It is not very smart to use http:// and post clear text passwords across the Internet… Switch to use https:// when you can – Most hosting companies should provide a free SSL certificate nowadays, and there are a few affordable ones anyway.

 

LINKS & REFERENCES

 

TUTORIAL VIDEO

 

THE END

Thank you for reading, and that’s it for this tutorial. I hope it has helped you with your project, but please do remember that this guide is ultimately a skeleton frame only – You have to beef up on the security and add access control in your own project. If you have anything to share, feel free to comment below. Good luck, and happy coding!

20 thoughts on “4 Steps Simple User Login System With PHP MySQL (Free Download!)”

  1. I’m not a programmer so when things don’t work as I expect them to then it can be a little confusing. Your code works great and very straightforward to implement and works in the sense that if a user is logged out then you can’t get view the page, which in my case is “home.php” and which you could view when signed in.
    However when I signed out and then went to “…/home.php” whilst it didn’t display that page the problem os it just shows a white screen and just hangs even though the re-direct is set to login.php. So can you help on this please?
    Also, and perhaps I am being dense here, but how do I create a Registration page so I can take on board new users?
    Many thanks in anticipation.
    Brian

Leave a Comment

Your email address will not be published.