Login and Register Script In PHP PDO With MySQL - onlyxcodes

Tuesday 2 April 2019

Login and Register Script In PHP PDO With MySQL

Hi, welcome back guys, in the previous tutorial, I discussed codes for PHP CRUD operations with PDO. Now I'm going to explaining Login and Register Script in PHP PDO with MySQL Database in this tutorial.


In this project, I use the PHP password hashing function to create the password encryption unit. The password hashing function builds up in PHP 5.5 edition and includes in PHP 7 edition which has become widely used to construct secure encrypted passwords in your dynamic PHP web project.


The second most valuable element that I add in this project the user login access facility with the session object. Its unique information to save users.


Well, I'm working on how to create encrypted passwords on the login page, and how to check encrypted passwords. And how to retain exclusive access to user logins with session objects and encrypted passwords. I hope this registration and login script will benefit your project.


login and register script in php pdo with mysql - onlyxcodes

Table Content

1. Project Configuration

2. Database and Table Making

3. connection.php

4. Password Hashed / Encrypt Guidelines

5. index.php [ login form ]

    5.1 PHP Login Code With PDO

    5.2 Login Code Logic Explanation

6. register.php [ registration form ]

    6.1 PHP Registration Code With PDO

    6.2 Registration Code Logic Explanation

7. welcome.php

    7.1 Welcome Page Code Logic Explanation

8. logout.php


1. Project Configuration

I assume the XAMPP server is installed on your system. Look for path of project C:\xampp\htdocs\Login-Register-PHP-PDO.


I installed the XAMPP server in C: drive here and I set up this project inside this drive. But you can set up your specific drive you want XAMPP server installed.


The project directory structure of login and register script in PHP PDO with XAMPP server

In this project, I have created 5 PHP files with PDO extension to do login and registration script.


connection.php


index.php


register.php


welcome.php


logout.php


2. Database And Table Making

Execute the below SQL code to build a database and a table to save the required user fields.


CREATE DATABASE php_pdo_login_db;
CREATE TABLE `tbl_user` (
  `user_id` int(11) NOT NULL,
  `username` varchar(15) NOT NULL,
  `email` varchar(40) NOT NULL,
  `password` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT; 

make user table in the database

3. connection.php

Since creating a database and table, we continue to create a new file named 'connection.php' that includes database connection code for error managing within the try/catch block.


<?php
$db_host="localhost"; //localhost server 
$db_user="root"; //database username
$db_password=""; //database password   
$db_name="php_pdo_login_db"; //database name

try
{
 $db=new PDO("mysql:host={$db_host};dbname={$db_name}",$db_user,$db_password);
 $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOEXCEPTION $e)
{
 $e->getMessage();
}

?>

4. Password Hashed / Encrypt Guidelines

PHP 5.5 and PHP 7 edition have four types of password hashing function below see.


password_hash () – used to hash the password.


password_verify () – to verify a password with a hashed password.


password_get_info – Returns information about the given hash.


password_needs_rehash – Checks if the given hash matches the given options.


PHP's manual site php.net takes over all the above function notes.


password_hash() :


The entire project hash password by password_hash() function. See the first parameter $password that includes a straightforward 123456 password and the second parameter PASSWORD_DEFAULT used to describe the hash password algorithm.


 <?php

$password = 123456;
$hash_enrypt = password_hash($password, PASSWORD_DEFAULT)

/*
"123456" it will be become

$2y$10$4EPUftoDEwiUonmL.x9zu.YOJL8qjrfSVRybkM8Dwo1xgBZPvyBRK

*/

?>

password_verify() :


Using the password_verify() function to verify password string with match hashed/encrypted password string after it is true and false.


<?php

$password = 123456;
$hash_encrypt = "$2y$10$4EPUftoDEwiUonmL.x9zu.YOJL8qjrfSVRybkM8Dwo1xgBZPvyBRK";

password_verify($password, $hash_encrypt);

/*
 the password match it will return TRUE.
*/

?>

5. index.php [ login form ]

Index.php as the login form that takes username/email and password to the welcome page for users to enter. If any error and success messages appeared in login codes apart from variables $errorMsg and $loginMsg displaying suitable custom messages.


<?php
if(isset($errorMsg))
{
 foreach($errorMsg as $error)
 {
 ?>
  <div class="alert alert-danger">
   <strong><?php echo $error; ?></strong>
  </div>
    <?php
 }
}
if(isset($loginMsg))
{
?>
 <div class="alert alert-success">
  <strong><?php echo $loginMsg; ?></strong>
 </div>
<?php
}
?> 
<form method="post" class="form-horizontal">
     
 <div class="form-group">
 <label class="col-sm-3 control-label">Username or Email</label>
 <div class="col-sm-6">
 <input type="text" name="txt_username_email" class="form-control" placeholder="enter username or email" />
 </div>
 </div>
     
 <div class="form-group">
 <label class="col-sm-3 control-label">Password</label>
 <div class="col-sm-6">
 <input type="password" name="txt_password" class="form-control" placeholder="enter passowrd" />
 </div>
 </div>
    
 <div class="form-group">
 <div class="col-sm-offset-3 col-sm-9 m-t-15">
 <input type="submit" name="btn_login" class="btn btn-success" value="Login">
 </div>
 </div>
    
 <div class="form-group">
 <div class="col-sm-offset-3 col-sm-9 m-t-15">
 You don't have a account register here? <a href="register.php"><p class="text-info">Register Account</p></a>  
 </div>
 </div>
     
</form>

5.1 PHP Login Code With PDO

Identifying the specific user name or email and encrypted password from the database table is the responsibility for these codes. If both values are detected in the table then a session will begin and enable the user to enter the welcome page, otherwise, the relevant message will be displayed. 


<?php

require_once 'connection.php';

session_start();

if(isset($_SESSION["user_login"])) //check condition session user login not direct back to index.php page
{
 header("location: welcome.php");
}

if(isset($_REQUEST['btn_login'])) //button name is "btn_login" 
{
 $username =strip_tags($_REQUEST["txt_username_email"]); //textbox name "txt_username_email"
 $email  =strip_tags($_REQUEST["txt_username_email"]); //textbox name "txt_username_email"
 $password =strip_tags($_REQUEST["txt_password"]);   //textbox name "txt_password"
  
 if(empty($username)){      
  $errorMsg[]="please enter username or email"; //check "username/email" textbox not empty 
 }
 else if(empty($email)){
  $errorMsg[]="please enter username or email"; //check "username/email" textbox not empty 
 }
 else if(empty($password)){
  $errorMsg[]="please enter password"; //check "passowrd" textbox not empty 
 }
 else
 {
  try
  {
   $select_stmt=$db->prepare("SELECT * FROM tbl_user WHERE username=:uname OR email=:uemail"); //sql select query
   $select_stmt->execute(array(':uname'=>$username, ':uemail'=>$email)); //execute query with bind parameter
   $row=$select_stmt->fetch(PDO::FETCH_ASSOC);
   
   if($select_stmt->rowCount() > 0) //check condition database record greater zero after continue
   {
    if($username==$row["username"] OR $email==$row["email"]) //check condition user taypable "username or email" are both match from database "username or email" after continue
    {
     if(password_verify($password, $row["password"])) //check condition user taypable "password" are match from database "password" using password_verify() after continue
     {
      $_SESSION["user_login"] = $row["user_id"]; //session name is "user_login"
      $loginMsg = "Successfully Login...";  //user login success message
      header("refresh:2; welcome.php");   //refresh 2 second after redirect to "welcome.php" page
     }
     else
     {
      $errorMsg[]="wrong password";
     }
    }
    else
    {
     $errorMsg[]="wrong username or email";
    }
   }
   else
   {
    $errorMsg[]="wrong username or email";
   }
  }
  catch(PDOException $e)
  {
   $e->getMessage();
  }  
 }
}
?>

5.2 Login Code Logic Explanation :

Row no 3 – Use function require_once to include connection.php database connection file. Its file object is the $db help to select the user login access query to execute SQL.


Row no 5 – Start the session with the session_start() function by logging in to the session object by the user.


Row no 7 to 10 – if condition finds the 'user_login' session object if it was found to send header() function to the welcome page. Because session base login users can not access the login page directly, they are required to log out from the welcome page. 


Row no 12 – Use the $_REQUEST [ ] method array to get the btn_login attribute value of the login form button. The isset() function set up this attribute value click event.


Row no 14 to 16 – The $_REQUEST[ ] array method that gets txt_username_email and txt_password values from the name of the text box attribute in the login form. And they'll be assigning $username, $email and $password to created new variables. 


Row no 18 to 26 –  if and else condition, the empty() function checks that all text box variable values are not empty.


Row no 28 to 33 – Within else condition open try/catch block. apply the select PDO query in the prepare() statement and select all records.


The array() function binds the value of the variables :uname and :uemail in selected query placed within the execute() function. The $username and $email variables keep those values.


PDOStatement:: fetch method returns a row from the result set. PDO:: FETCH_ASSOC parameter informs PDO to return array value indexed by table column username and email. The $row is an array. 


Row no 35 – The number of rows returnable by rowCount() function is greater than zero (> 0) if condition check returns. 


Row no 37 –  if condition, using = = operator check to match the user-typed form field username and email values from the table.


Note – The operator use = = is equal to or not for both operand values.


The username and email values of both the text box hold $username, $email variables. And retrieve able table fields of username and email both values hold by $row array variable.


Row no 39 to 44 – If condition, the function password_verify () checks the value of the password text box match from the hashed record of the table password.


The password text box value keeps the variable $password and retrieve able table filed of password value keep by $row variable.


Above all conditions are true then the session will start paste user_login session object in $_SESSION [] array and assign it to the table id. Apply the successful login message and the header() function will keep this message within 2 seconds, it will be sent in the welcome page.


Note – I do not discuss any else condition in login codes that any else condition will display a particular error message when login codes are triggered. And that error message assign into $errorMsg[] array variable.


6. register.php [ registeration form ]

This page contains a registration form with three input box username, email, and password for registering new users data into the database.


If any message of success and error detects in the registration code then the variable $errorMsg and $registerMsg display the appropriate message. 


<?php
if(isset($errorMsg))
{
 foreach($errorMsg as $error)
 {
 ?>
  <div class="alert alert-danger">
   <strong>WRONG ! <?php echo $error; ?></strong>
  </div>
    <?php
 }
}
if(isset($registerMsg))
{
?>
 <div class="alert alert-success">
  <strong><?php echo $registerMsg; ?></strong>
 </div>
<?php
}
?> 
<form method="post" class="form-horizontal">
        
 <div class="form-group">
 <label class="col-sm-3 control-label">Username</label>
 <div class="col-sm-6">
 <input type="text" name="txt_username" class="form-control" placeholder="enter username" />
 </div>
 </div>
    
 <div class="form-group">
 <label class="col-sm-3 control-label">Email</label>
 <div class="col-sm-6">
 <input type="text" name="txt_email" class="form-control" placeholder="enter email" />
 </div>
 </div>
     
 <div class="form-group">
 <label class="col-sm-3 control-label">Password</label>
 <div class="col-sm-6">
 <input type="password" name="txt_password" class="form-control" placeholder="enter passowrd" />
 </div>
 </div>
     
 <div class="form-group">
 <div class="col-sm-offset-3 col-sm-9 m-t-15">
 <input type="submit"  name="btn_register" class="btn btn-primary " value="Register">
 </div>
 </div>
    
 <div class="form-group">
 <div class="col-sm-offset-3 col-sm-9 m-t-15">
 You have a account register here? <a href="index.php"><p class="text-info">Login Account</p></a>  
 </div>
 </div>
     
</form>

6.1 PHP Registration Code With PDO


See PHP registration codes below for registering new user data in the database. These codes are also responsible for checking duplicate usernames or email from the database while signing in if any duplicate found then its display error message sorry email or username already exists.


<?php

require_once "connection.php";

if(isset($_REQUEST['btn_register'])) //button name "btn_register"
{
 $username = strip_tags($_REQUEST['txt_username']); //textbox name "txt_email"
 $email  = strip_tags($_REQUEST['txt_email']);  //textbox name "txt_email"
 $password = strip_tags($_REQUEST['txt_password']); //textbox name "txt_password"
  
 if(empty($username)){
  $errorMsg[]="Please enter username"; //check username textbox not empty 
 }
 else if(empty($email)){
  $errorMsg[]="Please enter email"; //check email textbox not empty 
 }
 else if(!filter_var($email, FILTER_VALIDATE_EMAIL)){
  $errorMsg[]="Please enter a valid email address"; //check proper email format 
 }
 else if(empty($password)){
  $errorMsg[]="Please enter password"; //check passowrd textbox not empty
 }
 else if(strlen($password) < 6){
  $errorMsg[] = "Password must be atleast 6 characters"; //check passowrd must be 6 characters
 }
 else
 { 
  try
  { 
   $select_stmt=$db->prepare("SELECT username, email FROM tbl_user 
          WHERE username=:uname OR email=:uemail"); // sql select query
   
   $select_stmt->execute(array(':uname'=>$username, ':uemail'=>$email)); //execute query 
   $row=$select_stmt->fetch(PDO::FETCH_ASSOC); 
   
   if($row["username"]==$username){
    $errorMsg[]="Sorry username already exists"; //check condition username already exists 
   }
   else if($row["email"]==$email){
    $errorMsg[]="Sorry email already exists"; //check condition email already exists 
   }
   else if(!isset($errorMsg)) //check no "$errorMsg" show then continue
   {
    $new_password = password_hash($password, PASSWORD_DEFAULT); //encrypt password using password_hash()
    
    $insert_stmt=$db->prepare("INSERT INTO tbl_user (username,email,password) VALUES
                (:uname,:uemail,:upassword)");   //sql insert query     
    
    if($insert_stmt->execute(array( ':uname' =>$username, 
                                    ':uemail'=>$email, 
                                    ':upassword'=>$new_password))){
             
     $registerMsg="Register Successfully..... Please Click On Login Account Link"; //execute query success message
    }
   }
  }
  catch(PDOException $e)
  {
   echo $e->getMessage();
  }
 }
}
?>

6.2 Registration Codes Logic Explanation :

Row no 3 – Use the require_once function adds the connection file to the database. Using database object $db to fire PDO queries.


Row no 5 – Using the $_REQUEST[ ] array method we get attribute value btn_register for the registration form button name. And this attribute value clicks event targeting by the isset() function.


Row no 7 to 9 – Using $_REQUEST[ ] array method gets all values of txt_username, txt_email, and txt_password by name attribute in the registration form fields.


Row no 11 to 25 –  If and else condition check form fields all values not null using the function empty(). As well as checking correct email address format and password length minimum of 6 characters must be required.


filter_var – Filter a variable with a specified filter ( according to php.net ).


FILTER_VALIDATE_EMAIL – The FILTER_VALIDATE_EMAIL filter validates an e-mail address ( according to php.net ).


Here, I filter the $email variable value from user input to check the correct email address format.


strlen() – Returns the length of the given string. ( according to php.net ).


I check here the $password variable value that takes user inputs less than six (< 6) or not.


Within try/catch block apply PDO select query under in prepare() statement and select the username and email value from the table.


Inside the execute() function the array() function bind the value of the variables :uname and :uemail in query location. The $username and $email variables hold both those values. The function execute() run the PDO query statement.


PDOStatement:: fetch method extracts a row from the set of results. PDO:: FETCH_ASSOC parameter says PDO to recover array value indexed by username and email of the table column. The array is $row.


Row no 36 to 41 – If and if-else condition checks the new user has entered the username and the email value already exists from the table or not.


Row no 42 – else if condition, the isset () function checks that no error has been found in the variable $errorMsg.


Row no 44 – The password_hash () function consists of two parameters.


The first password text box value holding the variable $password. And the second PASSWORD_DEFAULT parameter used to define the hash password algorithm.


The hashed/encrypt password will be generated and this password store will be created in the variable $new_password.


Row no 46 to 54 – Apply the PDO insert query under in prepare() statement.


Under in execute() function the function array () binds the values :uname, :uemail and :upassword in the insert query. All parameter values carry variables along with $username,$email and $new_password variables.


If the insert query perfectly executes then to displays the register successfully message.


7. welcome.php

This page displays the logging in the user's welcome message with username as well as a hyperlink to logout the user and diverts the login or index.php page.


<center>
 <h2>
 <?php
    
 require_once 'connection.php';
    
 session_start();

 if(!isset($_SESSION['user_login'])) //check unauthorize user not access in "welcome.php" page
 {
  header("location: index.php");
 }
    
 $id = $_SESSION['user_login'];
    
 $select_stmt = $db->prepare("SELECT * FROM tbl_user WHERE user_id=:uid");
 $select_stmt->execute(array(":uid"=>$id));
 
 $row=$select_stmt->fetch(PDO::FETCH_ASSOC);
    
 if(isset($_SESSION['user_login']))
 {
 ?>
  Welcome,
 <?php
   echo $row['username'];
 }
 ?>
 </h2>
 
  <a href="logout.php">Logout</a>
  
</center>

7.1 Welcome Page Codes Logic Explanation :

Friends, I skip the simple logic of how to include the database connection file and how to start the session using session_start() because I have already discussed the login and registration codes above.


Row no 9 to 12 – If condition, To find a user_login session object, we use the $_SESSION[ ] superglobal array method. If not found then header () function sends to the index page. The unauthorized user does not have access to the welcome page without the session.


Row no 14 – session object user_login store in new $id variable.


Row no 16 to 19 – Apply PDO select query inside the prepare() statement and select the user Id for that login.


The execute() function executes the query as well as within this function the array() function bind the :uid value place in select query. And this value carries by $id variable.


PDOStatement:: fetch method select a row from the set of results. PDO:: FETCH_ASSOC parameter orders PDO to retrieve array value indexed by the Id of the table column. The array is $row.


Finally, the echo method displays the unique user's username.


8. logout.php

In this file, we destroy the session from the welcome page, along with clicking on the logout hyperlink, and send it all to the index.php / login page. 


<?php
session_start();

header("location:index.php");

session_destroy();

?>


Download Codes

21 comments:

  1. Dear hamid

    Really u are a great man. am glad for all the information u have placed on your site . it has helped me alot. am grateful

    thank u so much for sharing your knowledge , keep it up

    ReplyDelete
  2. Saying that password_verify() checks against a hashed/encrypted password string is 50% wrong. password_hash() and password_verify() has nothing to do with encryption (which suggests that they can be decrypted, which they can't.) It's all hashes.

    ReplyDelete
  3. I got this warning when trying to register user
    Warning: Trying to access array offset on value of type bool in C:\xampp8\htdocs\login1\register.php on line 36

    Warning: Trying to access array offset on value of type bool in C:\xampp8\htdocs\login1\register.php on line 39

    ReplyDelete
  4. Dear Mr Hamid, firstly have to thanks for this code & I successfully apply it. My question is, how to create Masterlogin that comes with roles..like your previous post "Multi User Role Bases Login in PHP with MySQL PDO" ?

    OR .. how to implement Password Hashed / Encrypt in your "Multi User Role Bases Login in PHP with MySQL PDO"

    ReplyDelete
    Replies
    1. Hi, Zailir Othman on the registration page implements password_hash() function to generate secure password and in login codes use password_verify() function to verify password on the article Multi User Role Based login System.

      Thank you keep visiting and like on Facebook.

      Delete
    2. Thank you very much sir..most appreciated !

      Delete
    3. Welcome, like on Facebook and keep visiting

      Delete
  5. Hi Mr Hamid..that is correct to place here?: the password_verify($dbpassword =$row["password"]);
    Because I got the error "PHP Warning: password_verify() expects exactly 2 parameters, 1 given in.."

    $select_stmt=$db->prepare("SELECT username, password, role FROM masterlogin
    WHERE
    username=:uusername AND password=:upassword AND role=:urole");
    $select_stmt->bindParam(":uusername", $username);
    $select_stmt->bindParam(":upassword", $password);
    $select_stmt->bindParam(":urole", $role);
    $select_stmt->execute();

    while($row=$select_stmt->fetch(PDO::FETCH_ASSOC))
    {
    $dbusername =$row["username"];
    password_verify($dbpassword =$row["password"]);
    //$dbpassword =$row["password"];
    $dbrole =$row["role"];
    }
    if(($username!=null AND $password!=null AND $role!=null))
    {
    if($select_stmt->rowCount()>0)
    {
    if($username==$dbusername AND $password==$dbpassword AND $role==$dbrole)
    {
    switch($dbrole)
    {

    ReplyDelete
    Replies
    1. First put $dbpassword = $row["password"] as it is.

      Next, try this condition if (password_verify($password, $dbpassword)).

      Note: above condition put after this condition if($username==$dbusername AND $role==$dbrole). Remove $password==$dbpassword within this condition.

      Delete
  6. I so sorry sir to disturb you..I had apply your suggestion but I get error "Wrong username or password or role" - the code I reply as below (sorry if I'm wrong)

    $select_stmt=$db->prepare("SELECT username, password, role FROM masterlogin
    WHERE
    username=:uusername AND password=:upassword AND role=:urole");
    $select_stmt->bindParam(":uusername", $username);
    $select_stmt->bindParam(":upassword", $password);
    $select_stmt->bindParam(":urole", $role);
    $select_stmt->execute();

    while($row=$select_stmt->fetch(PDO::FETCH_ASSOC))
    {
    $dbusername =$row["username"];
    $dbpassword =$row["password"];
    $dbrole =$row["role"];
    }
    if(($username!=null AND $password!=null AND $role!=null))
    {
    if($select_stmt->rowCount()>0)
    {
    if($username==$dbusername AND $role==$dbrole)
    $dbpassword=$row["password"];
    if(password_verify($password, $dbpassword))
    {
    switch($dbrole)
    {

    ReplyDelete
    Replies
    1. remove $dbpassword=$row["password"] before password_verify() condition

      Delete
  7. Thanks..

    After I remove $dbpassword=$row["password"], I got error

    "Undefined variable: dbpassword in..line 42"

    Line 42 refer to:-

    WHERE username=:uusername AND password=:upassword AND role=:urole");

    ReplyDelete
    Replies
    1. remove password=:upassword and remove $select_stmt->bindParam(":upassword", $password).

      Try select * from masterlogin query.

      Put below

      WHERE username=:username AND role=:urole")

      within While condition put $dbpassword = $row["password"].

      and apply this condition if(password_verify($password, $dbpassword))

      Delete
    2. Thank you very much Mr Hamid. Finally I successfully apply your advise and solve my problem!

      Below is the code with your advise(may be can help other people that facing same problem)

      $select_stmt=$db->prepare("SELECT * FROM masterlogin
      WHERE username=:uusername AND role=:urole");
      $select_stmt->bindParam(":uusername", $username);
      $select_stmt->bindParam(":urole", $role);
      $select_stmt->execute();

      while($row=$select_stmt->fetch(PDO::FETCH_ASSOC))
      {
      $dbusername =$row["username"];
      $dbpassword =$row["password"];
      if(password_verify($password, $dbpassword));
      $dbrole =$row["role"];
      }
      if(($username!=null AND $password!=null AND $role!=null))
      {
      if($select_stmt->rowCount()>0)
      {
      if($username==$dbusername AND $role==$dbrole)
      {
      switch($dbrole)
      {

      Delete
    3. Welcome keep visiting and share your friends

      Delete
  8. Salam Mr Hamid..I have one more question: I have one domain with two sub-page: Example test.com/demo1 & test.com/demo2. Every page I created different login database. Because it is not a different site/domain, so when I login in one page then another page also login. I was thinking we can use $_SESSION to prevent this, but I do not know how to do that..do you have any idea?

    ReplyDelete
    Replies
    1. Yes use $_SESSION and apply different session name in login codes.

      Include session destroy method after user click on the logout link.


      Delete
  9. Outstanding tutorial. I was having a terrible time getting PHP's password_hash() and password_verify() to work and your code executes them perfectly. I was perplexed/annoyed at first by the image-type code snippets, but I eventually found the Download button, piped the SQL into my database, changed four variables in the connection script, and everything just worked!

    ReplyDelete

Post Bottom Ad