User Registration in PHP with Login: Form with MySQL and Code Download

Last modified on January 3rd, 2020 by Vincy.

Are you looking for code to create user registration in PHP? A lightweight form with MySQL database backend. Read on!

There are lots of PHP components for user registration available on the Internet. But these contain heavy stuff and lots of dependencies.

An appropriate code should be lightweight, secure, feature-packed and customizable. I am going to explain how to code this user registration in PHP with a login.

With this code, you can customize or put any add-ons as per your need and enhance it.

User Registration in PHP with Login Form

What is inside?

  1. Example code for user registration in PHP
  2. Create user registration and login form
  3. Registration and login form validation
  4. Process user registration in PHP
  5. PHP login authentication code
  6. User dashboard
  7. MySQL database script
  8. Screenshot of user registration and login form

Example code for user registration in PHP

In this example, I have created user registration in PHP with the login script. In a previous article, we have seen how to create a login script with PHP session.

On a landing page, it shows a login form with a signup link. The registered user can enter their login details with the login form. Once done, he can get into the dashboard after authentication.

If the user does not have an account, then he can click the signup option to create a new account.

The user registration form requests username, email, password from the user. On submission, PHP code allows registration if the email does not already exist.

This example code has client-side validation for validating the entered user details. And also, it includes contains the server-side uniqueness test. The user email is the base to check uniqueness before adding the users to the MySQL database.

This linked article includes a basic example of implementing user registration in PHP and MySQL.

File structure

User Registration File Structure

Create user registration and login form

I have created three HTML view login form, registration form and the dashboard for this code.

Below HMTL code is for displaying the login form to the user. In this form, it has two inputs to allow the user to enter their username and password.

Without these details, a validation code will not allow the login to proceed. The login form tag’s on-click attribute is with loginValidation(). This function contains the login form validation script.

On submitting this login form, the PHP code will validate the user. If the users clear the authentication, then it will redirect him to the dashboard.

If the user attempts to log in with the wrong data, then the code will display a login error message in the login form. If you want to limit the failed login attempts, the linked article has an example of that.

See also login form with forgot password and remember me.

login-form.php

<div class="sign-up-container">
			<div class="login-signup">
				<a href="user-registration-form.php">Sign up</a>
			</div>
			<div class="signup-align">
				<form name="login" action="" method="post"
					onsubmit="return loginValidation()">
					<div class="signup-heading">Login</div>
				<?php if(!empty($loginResult)){?>
				<div class="error-msg"><?php echo $loginResult;?></div>
				<?php }?>
				<div class="row">
						<div class="inline-block">
							<div class="form-label">
								Username<span class="required error" id="username-info"></span>
							</div>
							<input class="input-box-330" type="text" name="username"
								id="username">
						</div>
					</div>
					<div class="row">
						<div class="inline-block">
							<div class="form-label">
								Password<span class="required error" id="signup-password-info"></span>
							</div>
							<input class="input-box-330" type="password"
								name="signup-password" id="signup-password">
						</div>
					</div>
					<div class="row">
						<input class="sign-up-btn" type="submit" name="login-btn"
							id="login-btn" value="Login">
					</div>

				</form>
			</div>
		</div>

This is a user registration form getting minimal user data from the user. All form fields are mandatory.

It will pass-through a JavaScript validation before processing the user registration in PHP.

On submitting the registration form fields, it will invoke the signupValidation() JavaScript method. In this method, it validates with the non-empty check, email format, and the password match.

After validation, the PHP registration will take place with the posted form data. 

user-registration-form.php

<HTML>
<HEAD>
<TITLE>Registration</TITLE>
<link href="./assets/css/phppot-style.css" type="text/css"
	rel="stylesheet" />
<link href="./assets/css/user-registration.css" type="text/css"
	rel="stylesheet" />
</HEAD>
<BODY>
	<div class="phppot-container">
		<div class="sign-up-container">
			<div class="login-signup">
				<a href="login-form.php">Login</a>
			</div>
			<div class="">
				<form name="sign-up" action="" method="post"
					onsubmit="return signupValidation()">
					<div class="signup-heading">Registration</div>
				<?php 
				if(!empty($registrationResponse["status"]))
				{
				?>
                    <?php 
                    if($registrationResponse["status"] == "error")
                    {
                    ?>
				    <div class="server-response error-msg"><?php echo $registrationResponse["message"]; ?></div>
                    <?php 
				    } 
				    else if($registrationResponse["status"] == "success")
				    {
                    ?>
                    <div class="server-response success-msg"><?php echo $registrationResponse["message"]; ?></div>
                    <?php 
				    }
                    ?>
				<?php 
				}
				?>
				<div class="error-msg" id="error-msg"></div>
					<div class="row">
						<div class="inline-block">
							<div class="form-label">
								Username<span class="required error" id="username-info"></span>
							</div>
							<input class="input-box-330" type="text" name="username"
								id="username">
						</div>
					</div>
					<div class="row">
						<div class="inline-block">
							<div class="form-label">
								Email<span class="required error" id="email-info"></span>
							</div>
							<input class="input-box-330" type="email" name="email" id="email">
						</div>
					</div>
					<div class="row">
						<div class="inline-block">
							<div class="form-label">
								Password<span class="required error" id="signup-password-info"></span>
							</div>
							<input class="input-box-330" type="password"
								name="signup-password" id="signup-password">
						</div>
					</div>
					<div class="row">
						<div class="inline-block">
							<div class="form-label">
								Confirm Password<span class="required error"
									id="confirm-password-info"></span>
							</div>
							<input class="input-box-330" type="password"
								name="confirm-password" id="confirm-password">
						</div>
					</div>
					<div class="row">
						<input class="sign-up-btn" type="submit" name="signup-btn"
							id="signup-btn" value="Sign up">
					</div>
				</form>
			</div>
		</div>
	</div>
</BODY>
</HTML>

Landing page loads login registration forms

index.php

<?php
use Phppot\Member;

session_start();
?>
<HTML>
<HEAD>
<TITLE>user-registration</TITLE>
<link href="./assets/css/phppot-style.css" type="text/css"
	rel="stylesheet" />
<link href="./assets/css/user-registration.css" type="text/css"
	rel="stylesheet" />
<script src="./vendor/jquery/jquery-3.3.1.js" type="text/javascript"></script>
</HEAD>
<BODY>
	<div class="phppot-container">
	<?php require_once "login-form.php";?>
	</div>
</BODY>
</HTML>

And the below CSS is for presenting this example of user registration in PHP.

user-registration.css

.sign-up-container {
	border: 1px solid;
	border-color: #9a9a9a;
	background: #fff;
	border-radius: 4px;
	padding: 10px;
	width: 350px;
	margin: 50px auto;
}

.page-header {
	float: right;
}

.login-signup {
	margin: 10px;
	text-decoration: none;
	float: right;
}

.login-signup a {
	text-decoration: none;
	color: #000;
	font-weight: 700;
}

.signup-heading {
	font-size: 2em;
	font-weight: bold;
	padding-top: 60px;
	text-align: center;
}

.inline-block {
	display: inline-block;
}

.row {
	margin: 15px 0px;
	text-align: center;
}

.form-label {
	margin-bottom: 5px;
	text-align: left;
}

input.input-box-330 {
	width: 250px;
}

.sign-up-container .error {
	color: #ee0000;
	padding: 0px;
	background: none;
	border: #ee0000;
}

.sign-up-container .error-field {
	border: 1px solid #d96557;
}

.sign-up-container .error:before {
	content: '*';
	padding: 0 3px;
	color: #D8000C;
}

.error-msg {
	padding-top: 10px;
	color: #D8000C;
	text-align: center;
}

.success-msg {
    padding-top: 10px;
	color: #23a600;
	text-align: center;
}

input.sign-up-btn {
	background-color: #ffb932;
	border-color: #ffc87a #e2a348 #da9d0a;
	text-align: center;
	cursor: pointer;
	color: #000;
	width: 250px
}

.signup-align {
	margin: 0 auto;
}

.page-content {
	font-weight: bold;
	padding-top: 60px;
	text-align: center;
}

Registration and login form validation

In this section, we are going to see the code created in JavaScript for form validation.

There are two methods for validating the form fields before sending the data to the PHP code.

On invalid data submission, the code will return a boolean false. It forces the user to enter the required fields by highlighting them.

login-form.php (JavaScript)

function loginValidation() {
	var valid = true;
	$("#username").removeClass("error-field");
	$("#password").removeClass("error-field");
	
	var UserName = $("#username").val();
	var Password = $('#signup-password').val();
    
	$("#username-info").html("").hide();
	$("#email-info").html("").hide();

	if (UserName.trim() == "") {
		$("#username-info").html("required.").css("color", "#ee0000").show();
		$("#username").addClass("error-field");
		valid = false;
	}
	if (Password.trim() == "") {
		$("#signup-password-info").html("required.").css("color", "#ee0000").show();
		$("#signup-password").addClass("error-field");
		valid = false;
	}
	if (valid == false) {
		$('.error-field').first().focus();
		valid = false;
	}
	return valid;	
}

user-registration-form.php (JavaScript)

function signupValidation() {
	var valid = true;
	
	$("#username").removeClass("error-field");
	$("#email").removeClass("error-field");
	$("#password").removeClass("error-field");
	$("#confirm-password").removeClass("error-field");
	
	var UserName = $("#username").val();
	var email = $("#email").val();
	var Password = $('#signup-password').val();
    var ConfirmPassword = $('#confirm-password').val();
	var emailRegex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
		
	$("#username-info").html("").hide();
	$("#email-info").html("").hide();

	if (UserName.trim() == "") {
		$("#username-info").html("required.").css("color", "#ee0000").show();
		$("#username").addClass("error-field");
		valid = false;
	}
	if (email == "") {
		$("#email-info").html("required").css("color", "#ee0000").show();
		$("#email").addClass("error-field");
		valid = false;
	} else if (email.trim() == "") {
		$("#email-info").html("Invalid email address.").css("color", "#ee0000").show();
		$("#email").addClass("error-field");
		valid = false;
	} else if (!emailRegex.test(email)) {
		$("#email-info").html("Invalid email address.").css("color", "#ee0000")
				.show();
		$("#email").addClass("error-field");
		valid = false;
	}
	if (Password.trim() == "") {
		$("#signup-password-info").html("required.").css("color", "#ee0000").show();
		$("#signup-password").addClass("error-field");
		valid = false;
	}
	if (ConfirmPassword.trim() == "") {
		$("#confirm-password-info").html("required.").css("color", "#ee0000").show();
		$("#confirm-password").addClass("error-field");
		valid = false;
	}
	if(Password != ConfirmPassword){
        $("#error-msg").html("Both passwords must be same.").show();
        valid=false;
    }
	if (valid == false) {
		$('.error-field').first().focus();
		valid = false;
	}
	return valid;	
}

Process user registration in PHP

After submitting the form details, it processes user registration in the PHP code.

This code uses default form submit to post data to the PHP. If you want the user registration code with AJAX, then we have to prevent the default submit with a script.

I have added this code at the beginning of the user-registration-form.php. It checks if the user submitted the form. Then, it invokes the registerMember() method defined in the Member model.

login-form.php (PHP code)

<?php
use Phppot\Member;
if (! empty($_POST["signup-btn"])) {
    require_once './Model/Member.php';
    $member = new Member();
    $registrationResponse = $member->registerMember();
}
?>

I have shown the Member model class code below. It contains all the functions related to this user registration and login example.

In the registerMember() function, it checks if the posted email already exists. If so, it truncates the registration flow and returns the error. Otherwise, it creates the Insert query to add the member record into the MySQL database.

The loginMember() function checks if there is any match for the entered login details. If the match found, it clears the authentication and allows the user to access the dashboard.

Model/Member.php

<?php
namespace Phppot;

class Member
{

    private $ds;

    function __construct()
    {
        require_once __DIR__ . './../lib/DataSource.php';
        $this->ds = new DataSource();
    }

    public function isMemberExists($email)
    {
        $query = 'SELECT * FROM tbl_member where email = ?';
        $paramType = 's';
        $paramValue = array(
            $email
        );
        $insertRecord = $this->ds->select($query, $paramType, $paramValue);
        $count = 0;
        if (is_array($insertRecord)) {
            $count = count($insertRecord);
        }
        return $count;
    }

    public function registerMember()
    {
        $result = $this->isMemberExists($_POST["email"]);
        if ($result < 1) {
            if (! empty($_POST["signup-password"])) {
                $hashedPassword = password_hash($_POST["signup-password"], PASSWORD_DEFAULT);
            }
            $query = 'INSERT INTO tbl_member (username, password, email) VALUES (?, ?, ?)';
            $paramType = 'sss';
            $paramValue = array(
                $_POST["username"],
                $hashedPassword,
                $_POST["email"]
            );
            $memberId = $this->ds->insert($query, $paramType, $paramValue);
            if(!empty($memberId)) {
                $response = array("status" => "success", "message" => "You have registered successfully.");
            }
        } else if ($result == 1) {
            $response = array("status" => "error", "message" => "Email already exists.");
        }
        return $response;
    }

    public function getMember($username)
    {
        $query = 'SELECT * FROM tbl_member where username = ?';
        $paramType = 's';
        $paramValue = array(
            $username
        );
        $loginUser = $this->ds->select($query, $paramType, $paramValue);
        return $loginUser;
    }

    public function loginMember()
    {
        $loginUserResult = $this->getMember($_POST["username"]);
        if (! empty($_POST["signup-password"])) {
            $password = $_POST["signup-password"];
        }
        $hashedPassword = $loginUserResult[0]["password"];
        $loginPassword = 0;
        if (password_verify($password, $hashedPassword)) {
            $loginPassword = 1;
        }
        if ($loginPassword == 1) {
            $_SESSION["username"] = $loginUserResult[0]["username"];
            $url = "./home.php";
            header("Location: $url");
        } else if ($loginPassword == 0) {
            $loginStatus = "Invalid username or password.";
            return $loginStatus;
        }
    }
}

PHP login authentication code

Below PHP code is for invoking the authentication function after login. It is in the login-form.php file above the HTML code.

user-registration-form.php (PHP Code)

<?php
if (! empty($_POST["login-btn"])) {
    require_once './Model/Member.php';
    $member = new Member();
    $loginResult = $member->loginMember();
}
?>

User dashboard

This is the user dashboard HTML code. It shows a welcome message with the logged-in member name. It also has an option to logout from the current session.

home.php

<?php
session_start();
$username = $_SESSION["username"];
?>
<HTML>
<HEAD>
<TITLE>Welcome</TITLE>
<link href="./assets/css/phppot-style.css" type="text/css"
	rel="stylesheet" />
<link href="./assets/css/user-registration.css" type="text/css"
	rel="stylesheet" />
</HEAD>
<BODY>
	<div class="phppot-container">
		<div class="page-header">
			<span class="login-signup"><a href="login-form.php">Logout</a></span>
		</div>
		<div class="page-content">Welcome <?php echo $username;?></div>
	</div>
</BODY>
</HTML>

DataSource.php

<?php
/**
 * Copyright (C) 2019 Phppot
 *
 * Distributed under MIT license with an exception that,
 * you don’t have to include the full MIT License in your code.
 * In essense, you can use it on commercial software, modify and distribute free.
 * Though not mandatory, you are requested to attribute this URL in your code or website.
 */
namespace Phppot;

/**
 * Generic datasource class for handling DB operations.
 * Uses MySqli and PreparedStatements.
 *
 * @version 2.5 - recordCount function added
 */
class DataSource
{

    // PHP 7.1.0 visibility modifiers are allowed for class constants.
    // when using above 7.1.0, declare the below constants as private
    const HOST = 'localhost';

    const USERNAME = 'root';

    const PASSWORD = 'test';

    const DATABASENAME = 'user-registration';

    private $conn;

    /**
     * PHP implicitly takes care of cleanup for default connection types.
     * So no need to worry about closing the connection.
     *
     * Singletons not required in PHP as there is no
     * concept of shared memory.
     * Every object lives only for a request.
     *
     * Keeping things simple and that works!
     */
    function __construct()
    {
        $this->conn = $this->getConnection();
    }

    /**
     * If connection object is needed use this method and get access to it.
     * Otherwise, use the below methods for insert / update / etc.
     *
     * @return \mysqli
     */
    public function getConnection()
    {
        $conn = new \mysqli(self::HOST, self::USERNAME, self::PASSWORD, self::DATABASENAME);

        if (mysqli_connect_errno()) {
            trigger_error("Problem with connecting to database.");
        }

        $conn->set_charset("utf8");
        return $conn;
    }

    /**
     * To get database results
     *
     * @param string $query
     * @param string $paramType
     * @param array $paramArray
     * @return array
     */
    public function select($query, $paramType = "", $paramArray = array())
    {
        $stmt = $this->conn->prepare($query);

        if (! empty($paramType) && ! empty($paramArray)) {

            $this->bindQueryParams($stmt, $paramType, $paramArray);
        }
        $stmt->execute();
        $result = $stmt->get_result();

        if ($result->num_rows > 0) {
            while ($row = $result->fetch_assoc()) {
                $resultset[] = $row;
            }
        }

        if (! empty($resultset)) {
            return $resultset;
        }
    }

    /**
     * To insert
     *
     * @param string $query
     * @param string $paramType
     * @param array $paramArray
     * @return int
     */
    public function insert($query, $paramType, $paramArray)
    {
        $stmt = $this->conn->prepare($query);
        $this->bindQueryParams($stmt, $paramType, $paramArray);

        $stmt->execute();
        $insertId = $stmt->insert_id;
        return $insertId;
    }

    /**
     * To execute query
     *
     * @param string $query
     * @param string $paramType
     * @param array $paramArray
     */
    public function execute($query, $paramType = "", $paramArray = array())
    {
        $stmt = $this->conn->prepare($query);

        if (! empty($paramType) && ! empty($paramArray)) {
            $this->bindQueryParams($stmt, $paramType, $paramArray);
        }
        $stmt->execute();
    }

    /**
     * 1.
     * Prepares parameter binding
     * 2. Bind prameters to the sql statement
     *
     * @param string $stmt
     * @param string $paramType
     * @param array $paramArray
     */
    public function bindQueryParams($stmt, $paramType, $paramArray = array())
    {
        $paramValueReference[] = & $paramType;
        for ($i = 0; $i < count($paramArray); $i ++) {
            $paramValueReference[] = & $paramArray[$i];
        }
        call_user_func_array(array(
            $stmt,
            'bind_param'
        ), $paramValueReference);
    }

    /**
     * To get database results
     *
     * @param string $query
     * @param string $paramType
     * @param array $paramArray
     * @return array
     */
    public function getRecordCount($query, $paramType = "", $paramArray = array())
    {
        $stmt = $this->conn->prepare($query);
        if (! empty($paramType) && ! empty($paramArray)) {

            $this->bindQueryParams($stmt, $paramType, $paramArray);
        }
        $stmt->execute();
        $stmt->store_result();
        $recordCount = $stmt->num_rows;

        return $recordCount;
    }
}

MySQL database script

Below SQL script shows the MySQL database table’s create statement. It also has the specification for the key and indexes.

User registration MySQL schema

Import this script into your PHP development root to execute this example.

sql/user-registration.sql

--
-- Database: `user-registration`
--

-- --------------------------------------------------------

--
-- Table structure for table `tbl_member`
--

CREATE TABLE `tbl_member` (
  `id` int(11) NOT NULL,
  `username` varchar(255) NOT NULL,
  `password` varchar(200) NOT NULL,
  `email` varchar(255) NOT NULL,
  `create_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Indexes for dumped tables
--

--
-- Indexes for table `tbl_member`
--
ALTER TABLE `tbl_member`
  ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT for table `tbl_member`
--
ALTER TABLE `tbl_member`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

Screenshot of user registration and login form

Login form with validation response:

User Login Form Output

User registration form server-side validation response:

Screenshot User Registration in-php PHP

Download

Comments to “User Registration in PHP with Login: Form with MySQL and Code Download”

  • Chieki says:

    I’m impressed by your works

    I want to be proficient in PHP

    Teach me PHP proficiency.

    I’ll pay you.

    I’m not kidding.

    • Vincy says:

      Thank you. I am in fact teaching PHP via this blog :-)

      Go through the menu in the left-sidebar and read through the articles. All the code are available for free download with no license restrictions. Download and practice using them. Best wishes!

Leave a Reply

Your email address will not be published. Required fields are marked *

↑ Back to Top

Share this Article