In this step-by-step tutorial guide you will learn how to create a session based user login and Sign-Up system using PHP with MySQL Database.
Create PHP Login & Sign-Up System
Here we will use MySQLi Procedural to build this login system. But don’t worry, at the end I will provide the same code in MySQLi OOP and PDO. Let’s start –
Step 1: Database Setup
- Database name:
php_login
- Table name:
users
- “users” table column:
id
name
email
password
Use the following SQL code to create the users
table and its column.
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(30) NOT NULL,
`email` varchar(30) NOT NULL,
`password` varchar(150) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`)
) ENGINE = InnoDB AUTO_INCREMENT = 12 DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci;
Step 2: Create the Project Folder
Open your xampp htdocs
folder or your localhost www
directory and create a folder called php-login-registration
. This is our project folder.
Step 3: Create PHP Files for this Project
Now in the project folder we need to create the following PHP files –
Step 4: “db_connection.php” for Database Connection
Change the database details according to yours –
<?php
$db_host = 'localhost';
$db_user = 'root';
$db_password = '';
$db_name = 'php_login';
$conn = mysqli_connect($db_host, $db_user, $db_password, $db_name);
// CHECKING THE DATABASE CONNECTION
if(mysqli_connect_errno()){
echo "Connection Failed - ".mysqli_connect_error();
exit;
}
Step 5: Write Code for User Signup
To sign-up a new user we need to create the on_register.php
and register.php
.
on_register.php
contains the on_register()
function which has the code for inserting new users. The on_register() function will be called when the sign up form (which is in the register.php
) is submitted.
1. “on_register.php” Handles User Signing Up
<?php
/**
* Handles user registration.
*
* @param mysqli $conn The database connection object.
* @return array Registration result.
*/
function on_register($conn)
{
// Sanitize and retrieve form data
$name = htmlspecialchars(trim($_POST['name']));
$email = trim($_POST['email']);
$pass = trim($_POST['password']);
// Check for empty fields
if (empty($name) || empty($email) || empty($pass)) {
$arr = [];
if (empty($name)) $arr["name"] = "Must not be empty.";
if (empty($email)) $arr["email"] = "Must not be empty.";
if (empty($pass)) $arr["password"] = "Must not be empty.";
return [
"ok" => 0,
"field_error" => $arr
];
}
// Validate email format
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
return [
"ok" => 0,
"field_error" => [
"email" => "Invalid email address."
]
];
}
// Check password length
if(strlen($pass) < 4){
return [
"ok" => 0,
"field_error" => [
"password" => "Must be at least 4 characters."
]
];
}
// Check if email is already registered
$sql = "SELECT `email` FROM `users` WHERE `email` = ?";
$stmt = mysqli_prepare($conn, $sql);
mysqli_stmt_bind_param($stmt, "s", $email);
mysqli_stmt_execute($stmt);
mysqli_stmt_store_result($stmt);
if(mysqli_stmt_num_rows($stmt) !== 0){
return [
"ok" => 0,
"field_error" => [
"email" => "This Email is already registered."
]
];
}
// Hash password
$pass = password_hash($pass, PASSWORD_DEFAULT);
// Insert user into database
$sql = "INSERT INTO `users` (`name`, `email`, `password`) VALUES (?,?,?)";
$stmt = mysqli_prepare($conn, $sql);
mysqli_stmt_bind_param($stmt, "sss", $name,$email,$pass);
$is_inserted = mysqli_stmt_execute($stmt);
if($is_inserted){
return [
"ok" => 1,
"msg" => "You have been registered successfully.",
"form_reset" => true
];
}
// Return error message if insertion failed
return [
"ok" => 0,
"msg" => "Something went wrong!"
];
}
2. “register.php” User can Signup
<?php
session_start();
// Redirect if user is already logged in
if(isset($_SESSION['logged_user_id'])){
header('Location: home.php');
exit;
}
// Handle form submission
if ($_SERVER["REQUEST_METHOD"] === "POST") {
require_once __DIR__ . "/db_connection.php";
require_once __DIR__."/on_register.php";
// Check if necessary fields are set
if (
isset($conn) &&
isset($_POST["name"]) &&
isset($_POST["email"]) &&
isset($_POST["password"])
) {
$result = on_register($conn);
}
}
// Determine if post values should be shown
$show = isset($result["form_reset"]) ? true : false;
// Function to echo post value and prevent XSS
function post_value($field){
global $show;
if(isset($_POST[$field]) && !$show){
echo 'value="'.trim(htmlspecialchars($_POST[$field])).'"';
return;
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sign Up</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<div class="container">
<h1>Sign Up</h1>
<form action="" method="POST" id="theForm">
<label for="user_name">Name: <span></span></label>
<input type="text" class="input" name="name" <?php post_value("name"); ?> id="user_name" placeholder="Your name">
<label for="user_email">Email: <span></span></label>
<input type="email" class="input" name="email" <?php post_value("email"); ?> id="user_email" placeholder="Your email">
<label for="user_pass">Password: <span></span></label>
<input type="password" class="input" name="password" <?php post_value("password"); ?> id="user_pass" placeholder="New password">
<!-- Display registration message -->
<?php if(isset($result["msg"])){ ?>
<p class="msg<?php if($result["ok"] === 0){ echo " error"; } ?>"><?php echo $result["msg"]; ?></p>
<?php } ?>
<input type="submit" value="Sign Up">
<div class="link"><a href="./login.php">Login</a></div>
</form>
</div>
<!-- JavaScript to display field errors -->
<?php if(isset($result["field_error"])){ ?>
<script>
let field_error = <?php echo json_encode($result["field_error"]); ?>;
let el = null;
let msg_el = null;
for(let i in field_error){
el = document.querySelector(`input[name="${i}"]`);
el.classList.add("error");
msg_el = document.querySelector(`label[for="${el.getAttribute("id")}"] span`);
msg_el.innerText = field_error[i];
}
</script>
<?php } ?>
</body>
</html>
Step 6: Write Code for User Login
Similar to the user registration the on_login.php
contain the code to login for existing users. The on_login() function will be called on submission of the login form which is in the login.php
.
1. “on_login.php” Handles user login
<?php
/**
* Handles user login.
*
* @param mysqli $conn The database connection object.
* @return array Login result.
*/
function on_login($conn){
// Retrieve and sanitize form data
$email = trim($_POST['email']);
$pass = trim($_POST['password']);
// Check for empty fields
if (empty($email) || empty($pass)) {
$arr = [];
if (empty($email)) $arr["email"] = "Must not be empty.";
if (empty($pass)) $arr["password"] = "Must not be empty.";
return [
"ok" => 0,
"field_error" => $arr
];
}
// Validate email format
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
return [
"ok" => 0,
"field_error" => [
"email" => "Invalid email address."
]
];
}
// Find user by email
$sql = "SELECT * FROM `users` WHERE `email` = ?";
$stmt = mysqli_prepare($conn, $sql);
mysqli_stmt_bind_param($stmt, "s", $email);
mysqli_stmt_execute($stmt);
$data = mysqli_stmt_get_result($stmt);
$row = mysqli_fetch_array($data, MYSQLI_ASSOC);
// If user doesn't exist
if($row === NULL){
return [
"ok" => 0,
"field_error" => [
"email" => "This email is not registered."
]
];
}
// Verify user password
$password_check = password_verify($pass, $row["password"]);
if($password_check === false){
return [
"ok" => 0,
"field_error" => [
"password" => "Incorrect Password."
]
];
}
// Set user id to session and redirect to home page
$_SESSION['logged_user_id'] = $row["id"];
header('Location: home.php');
exit;
}
2. “login.php” User can Login
<?php
/**
* Start session to manage user login state.
*/
session_start();
// Redirect if user is already logged in
if (isset($_SESSION['logged_user_id'])) {
header('Location: home.php');
exit;
}
// Handle form submission
if ($_SERVER["REQUEST_METHOD"] === "POST") :
require_once __DIR__ . "/db_connection.php";
require_once __DIR__ . "/on_login.php";
// Check if necessary fields are set
if (isset($conn) && isset($_POST["email"]) && isset($_POST["password"])) {
$result = on_login($conn);
}
endif;
/**
* Echoes post value securely to prevent XSS attacks.
*
* @param string $field The field name.
* @return void
*/
function post_value($field)
{
if (isset($_POST[$field])) {
echo 'value="' . trim(htmlspecialchars($_POST[$field])) . '"';
return;
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login Page</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<div class="container">
<h1>Login</h1>
<form action="" method="POST">
<label for="user_email">Email: <span></span></label>
<input type="email" class="input" name="email" <?php post_value("email"); ?> id="user_email" placeholder="Your email">
<label for="user_pass">Password: <span></span></label>
<input type="password" class="input" name="password" <?php post_value("password"); ?> id="user_pass" placeholder="Your password">
<input type="submit" value="Login">
<div class="link"><a href="./register.php">Sign Up</a></div>
</form>
</div>
<?php
// JavaScript to display field errors
if (isset($result["field_error"])) { ?>
<script>
let field_error = <?php echo json_encode($result["field_error"]); ?>;
let el = null;
let msg_el = null;
for (let i in field_error) {
el = document.querySelector(`input[name="${i}"]`);
el.classList.add("error");
msg_el = document.querySelector(`label[for="${el.getAttribute("id")}"] span`);
msg_el.innerText = field_error[i];
}
</script>
<?php } ?>
</body>
</html>
Step 7: After a User Logs in Successfully
After login successfully, the user will be redirected to the home.php
and the get_user.php
will fetch the user information from the database.
1. “get_user.php” Fetch User Data by User ID
<?php
/**
* Retrieves user data from the database by user ID.
*
* @param mysqli $conn The database connection object.
* @param int $id The user ID.
* @return array|false User data if found, otherwise false.
*/
function get_user($conn, $id){
// Validate user ID
if(!filter_var($id, FILTER_VALIDATE_INT)){
return false;
}
// Query to select user by ID
$sql = "SELECT * FROM `users` WHERE `id` = ?";
$stmt = mysqli_prepare($conn, $sql);
mysqli_stmt_bind_param($stmt, "i", $id);
mysqli_stmt_execute($stmt);
// Fetch user data
$data = mysqli_stmt_get_result($stmt);
$row = mysqli_fetch_array($data, MYSQLI_ASSOC);
// Return user data if found, otherwise false
if($row === NULL) return false;
return $row;
}
2. “home.php” Home Page for Logged In User
<?php
/**
* Start session and regenerate session ID for security.
*/
session_start();
session_regenerate_id(true);
// Redirect to logout page if user session is invalid
if (!isset($_SESSION['logged_user_id']) || empty($_SESSION['logged_user_id']) || !is_numeric($_SESSION['logged_user_id'])) {
header('Location: logout.php');
exit;
}
// Include necessary files
require_once __DIR__ . "/db_connection.php";
require_once __DIR__ . "/get_user.php";
// Get user data from the database based on session ID
$user = get_user($conn, $_SESSION['logged_user_id']);
// Redirect to logout page if user data is not found
if ($user === false) {
header('Location: logout.php');
exit;
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Home</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<div class="container">
<div class="profile">
<!-- Display user profile information -->
<img src="https://robohash.org/set_set3/<?php echo $user["id"]; ?>?size=200x200" alt="<?php echo $user["name"]; ?>">
<h2><?php echo $user["name"]; ?><span><?php echo $user["email"]; ?></span></h2>
<a href="./logout.php">Log out</a>
</div>
</div>
</body>
</html>
Step 8: “logout.php” Logout the Logged In User
<?php
/**
* Start the session.
*/
session_start();
// Unset all session variables
$_SESSION = array();
// If session cookies are used, delete the session cookie
if (ini_get("session.use_cookies")) {
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000,
$params["path"], $params["domain"],
$params["secure"], $params["httponly"]
);
}
// Destroy the session
session_destroy();
// Redirect to the login page
header("Location: login.php");
exit;
Step 9: Stylesheet for this Application “style.css”
Here is the CSS for this application user-interface:
@import url("https://fonts.googleapis.com/css2?family=Ubuntu:wght@300;400;700&display=swap");
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
font-size: 16px;
}
body {
background-color: #f7f7f7;
font-family: "Ubuntu", sans-serif;
margin: 0;
padding: 0;
color: #222222;
overflow-x: hidden;
overflow-wrap: break-word;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
padding: 50px;
}
.container {
background-color: white;
border-radius: 3px;
box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.175);
margin: 0 auto;
max-width: 450px;
padding: 40px;
}
.container h1 {
margin: 0 0 40px 0;
text-align: center;
}
input,
button {
font-family: "Ubuntu", sans-serif;
font-size: 1rem;
outline: none;
}
.input {
padding: 15px;
width: 100%;
margin-bottom: 15px;
border: 1px solid #bbbbbb;
border-radius: 3px;
}
.input:hover {
border-color: #999999;
}
.input:focus {
border-color: #0d6efd;
}
.input.error {
border-color: red !important;
}
label span {
color: red;
}
.msg {
border: 1px solid #66ba7a;
background: #f3ffd1;
padding: 10px;
border-radius: 3px;
}
.msg.error {
border-color: #e33b54;
background: #f9d7dc;
}
[type="submit"] {
background: #0d6efd;
color: white;
border: 1px solid rgba(0, 0, 0, 0.175);
border-radius: 3px;
padding: 12px 0;
cursor: pointer;
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
margin-top: 5px;
font-weight: bold;
width: 100%;
}
[type="submit"]:hover {
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
}
label {
font-weight: bold;
display: inline-block;
margin-bottom: 3px;
}
.link {
margin-top: 20px;
text-align: center;
}
.link a {
color: #0d6efd;
}
.profile {
text-align: center;
}
.profile img {
display: inline-block;
border: 3px solid #ccc;
border-radius: 50%;
width: 150px;
height: 150px;
}
h2 span {
display: block;
font-size: 15px;
font-weight: 400;
color: #888;
}
Step 10: Testing
PHP Login & Registration System with MySQLi OOP and PDO
Thank You … ❤️❤️❤️