PHP Login Script with Session

Last modified on August 12th, 2019 by Vincy.

In this tutorial, let us create a login script with a session in PHP. It has a simple example of implementing user authentication. This example uses a standard login form to get the user login details. And it preserves the login state with PHP sessions.

Login would be the first step of many application. Sometimes, part of privileged functionalities of application will ask users to login.

PHP Login Script with Session

So, the login script is an integral part of an application. I will present you the implementation of the login system with minimal code.

Authentication will help us to identify the genuine users. By enabling authentication, we can protect our website from anonymous access.

What is inside?

  1. Ways to create an authentication system
  2. About this example
  3. File structure
  4. User login interface
  5. PHP code to process login
  6. Get logged-in user profile data to show a welcome message
  7. Handling logout code in PHP
  8. Database script
  9. Test login details
  10. PHP login script with session output

Ways to create an authentication system

There are different ways of implementing an authentication system. The most popular way is to get the username and password via a login form and authenticate based on them.

Recently, authentication using OTP is also becoming the norm. The OTP will be dynamic and allowed for one-time.

For OTP authentication, the application sends it via wither via SMS or email. In a previous article, we have seen an example code in PHP to login by sending OTP via email.

About this example

In this example, it has users database with name, email, password and more details. It has a HTML form with inputs to get the user login credentials.

When the user submits their login details, then the PHP code will receive the posted data. It compares the entered data against the user database.

If match found, then it sets the user login session. In this authentication code, it preserves the user id in a PHP session. The existence of this session will state user authentication status.

After authentication, the PHP $_SESSION super global variable will contain the user id. That is, the $_SESSION[“member_id”] is set to manage the logged-in session. It will remain until log out or quit from the browser.

While logout, we unset all the session variables using PHP unset() function.

File structure

Below screenshot shows the organized file structure of this user login example. The Member.php is the model class with authentication functionalities. 

The DataSource.php file contains functions to get a connection and access database.

In a view directory, I have created all the UI related files for the login and the dashboard interface. It also contains a stylesheet used for this UI.

The index.php is the landing page that checks the user logged-in session. Then it redirects users either to log in or to the dashboard.

The login-action.php and logout.php files are the PHP endpoints. They handle actions as requested by the users via the interactive authentication Interface.

Login Script with Session Example File Structure

User login interface

Creating a HTML form to login is the first step. It is to get the login details from users.

In this example, it has two fields username and password for user login.

I have specified the validation function and the PHP endpoint with the form tag.

The HTML contains elements to display client-side validation error. Also, it has the code to show a server-side error response based on the login result.

<html>
<head>
<title>User Login</title>
<link href="./view/css/style.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <div>
        <form action="login-action.php" method="post" id="frmLogin" onSubmit="return validate();">
            <div class="demo-table">

                <div class="form-head">Login</div>
                <?php 
                if(isset($_SESSION["errorMessage"])) {
                ?>
                <div class="error-message"><?php  echo $_SESSION["errorMessage"]; ?></div>
                <?php 
                unset($_SESSION["errorMessage"]);
                } 
                ?>
                <div class="field-column">
                    <div>
                        <label for="username">Username</label><span id="user_info" class="error-info"></span>
                    </div>
                    <div>
                        <input name="user_name" id="user_name" type="text"
                            class="demo-input-box">
                    </div>
                </div>
                <div class="field-column">
                    <div>
                        <label for="password">Password</label><span id="password_info" class="error-info"></span>
                    </div>
                    <div>
                        <input name="password" id="password" type="password"
                            class="demo-input-box">
                    </div>
                </div>
                <div class=field-column>
                    <div>
                        <input type="submit" name="login" value="Login"
                        class="btnLogin"></span>
                    </div>
                </div>
            </div>
        </form>
    </div>
</body>
</html>

and the styles are,

body {
    font-family: Arial;
    color: #333;
    font-size: 0.95em;
}

.form-head {
    color: #191919;
    font-weight: normal;
    font-weight: 400;
    margin: 0;
    text-align: center;
    font-size: 1.8em;
}

.error-message {
    padding: 7px 10px;
    background: #fff1f2;
    border: #ffd5da 1px solid;
    color: #d6001c;
    border-radius: 4px;
    margin: 30px 10px 10px 10px;
}

.demo-table {
    background: #ffffff;
    border-spacing: initial;
    margin: 15px auto;
    word-break: break-word;
    table-layout: auto;
    line-height: 1.8em;
    color: #333;
    border-radius: 4px;
    padding: 30px;
    width: 380px;
    border: 1px solid;
    border-color: #e5e6e9 #dfe0e4 #d0d1d5;
}

.demo-table .label {
    color: #888888;
}

.demo-table .field-column {
    padding: 15px 10px;
}

.demo-input-box {
    padding: 13px;
    border: #CCC 1px solid;
    border-radius: 4px;
    width: 100%;
}

.btnLogin {
    padding: 13px;
    background-color: #5d9cec;
    color: #f5f7fa;
    cursor: pointer;
    border-radius: 4px;
    width: 100%;
    border: #5791da 1px solid;
    font-size: 1.1em;
}

.response-text {
    max-width: 380px;
    font-size: 1.5em;
    text-align: center;
    background: #fff3de;
    padding: 42px;
    border-radius: 3px;
    border: #f5e9d4 1px solid;
    font-family: arial;
    line-height: 34px;
    margin: 15px auto;
}

.terms {
    margin-bottom: 5px;
}

.dashboard {
    background: #d2edd5;
    text-align: center;
    margin: 15px auto;
    line-height: 1.8em;
    color: #333;
    border-radius: 4px;
    padding: 30px;
    max-width: 400px;
    border: #c8e0cb 1px solid;
}
.error-info {
    color: #FF0000;
    margin-left: 10px;
}
a.logout-button {
    color: #09f;
}

Login form validation

This script is for validating the login data at the client-side. If the users submit the login with empty fields then this script will return boolean false.

When it returns false, it displays a validation error message to the users. By returning boolean 0, the form validation script prevents login to proceed further.

    <script>
    function validate() {
        var $valid = true;
        document.getElementById("user_info").innerHTML = "";
        document.getElementById("password_info").innerHTML = "";
        
        var userName = document.getElementById("user_name").value;
        var password = document.getElementById("password").value;
        if(userName == "") 
        {
            document.getElementById("user_info").innerHTML = "required";
        	$valid = false;
        }
        if(password == "") 
        {
        	document.getElementById("password_info").innerHTML = "required";
            $valid = false;
        }
        return $valid;
    }
    </script>

PHP code to process login

The login-action.php file receives and handles the posted login data. It sends the username and password to the processLogin() function.

This method gets the login details and compares with the user database.

It prepares query and binds the login params with it to find the match from the database. If match found the processLogin will return the result.

On successful login, the login-action.php sets the logged-in user session. Otherwise, it will return error by saying “Invalid Credentials”.

<?php
namespace Phppot;

use \Phppot\Member;
if (! empty($_POST["login"])) {
    session_start();
    $username = filter_var($_POST["user_name"], FILTER_SANITIZE_STRING);
    $password = filter_var($_POST["password"], FILTER_SANITIZE_STRING);
    require_once (__DIR__ . "./class/Member.php");
    
    $member = new Member();
    $isLoggedIn = $member->processLogin($username, $password);
    if (! $isLoggedIn) {
        $_SESSION["errorMessage"] = "Invalid Credentials";
    }
    header("Location: ./index.php");
    exit();
}

Get logged-in user profile data to display a welcome message

This code is to display the dashboard after login. The PHP code embedded with this HTML is for getting the user session and the user data from the database.

It displays the welcome message by addressing the user with their display name.

The dashboard contains a logout link in addition to the welcome text.

<?php
namespace Phppot;

use \Phppot\Member;

if (! empty($_SESSION["userId"])) {
    require_once __DIR__ . './../class/Member.php';
    $member = new Member();
    $memberResult = $member->getMemberById($_SESSION["userId"]);
    if(!empty($memberResult[0]["display_name"])) {
        $displayName = ucwords($memberResult[0]["display_name"]);
    } else {
        $displayName = $memberResult[0]["user_name"];
    }
}
?>
<html>
<head>
<title>User Login</title>
<link href="./view/css/style.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <div>
        <div class="dashboard">
            <div class="member-dashboard">Welcome <b><?php echo $displayName; ?></b>, You have successfully logged in!<br>
                Click to <a href="./logout.php" class="logout-button">Logout</a>
            </div>
        </div>
    </div>
</body>
</html>

Member.php

This is the PHP class created in this example to handle the login process. The getMemberById method request DataSource to fetch the member results.

<?php
namespace Phppot;

use \Phppot\DataSource;

class Member
{

    private $dbConn;

    private $ds;

    function __construct()
    {
        require_once "DataSource.php";
        $this->ds = new DataSource();
    }

    function getMemberById($memberId)
    {
        $query = "select * FROM registered_users WHERE id = ?";
        $paramType = "i";
        $paramArray = array($memberId);
        $memberResult = $this->ds->select($query, $paramType, $paramArray);
        
        return $memberResult;
    }
    
    public function processLogin($username, $password) {
        $passwordHash = md5($password);
        $query = "select * FROM registered_users WHERE user_name = ? AND password = ?";
        $paramType = "ss";
        $paramArray = array($username, $passwordHash);
        $memberResult = $this->ds->select($query, $paramType, $paramArray);
        if(!empty($memberResult)) {
            $_SESSION["userId"] = $memberResult[0]["id"];
            return true;
        }
    }
}

Redirect users to Login or Dashboard based on Session

A landing page index.php contains code to check logged-in session and route users accordingly. The following code shows how to redirect users based on the session.

<?php
session_start();
if(!empty($_SESSION["userId"])) {
    require_once './view/dashboard.php';
} else {
    require_once './view/login-form.php';
}
?>

Handling logout in PHP

By clicking the logout link from the dashboard, it calls this PHP script. In this script, it clears the current login session and redirects users back to the login. The logout code is,

<?php 
session_start();
$_SESSION["user_id"] = "";
session_destroy();
header("Location: index.php");

DataSource.php

This class establishes a connection object to access the database based on the request. It has the select function to prepare a fetch query to return the results.

<?php
namespace Phppot;

/**
 * Generic datasource class for handling DB operations.
 * Uses MySqli and PreparedStatements.
 *
 * @version 2.3
 */
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 = '';

    const DATABASENAME = 'phpsamples';

    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)
    {
        print $query;
        $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=array());
        }
        $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 numRows($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;
    }
}

Database script

This script contains the CREATE statement for the registered_users table. Also, it has the data dump to check the example with test login details.

--
-- Table structure for table `registered_users`
--

CREATE TABLE `registered_users` (
  `id` int(8) NOT NULL,
  `user_name` varchar(255) NOT NULL,
  `display_name` varchar(255) NOT NULL,
  `password` varchar(255) NOT NULL,
  `email` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Dumping data for table `registered_users`
--

INSERT INTO `registered_users` (`id`, `user_name`, `display_name`, `password`, `email`) VALUES
(1, 'kate_91', 'Kate Winslet', 'ad5611358209efdc202d35127a160748', 'kate@wince.com');

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


--
-- AUTO_INCREMENT for table `registered_users`
--
ALTER TABLE `registered_users`
  MODIFY `id` int(8) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;
COMMIT;

Test login details

After setting this example code and database in your computer, use the following test data to check the example login system.

Username: kate_91
Password: kate@03

PHP login script with session output

This output screenshot shows the login form interface. It has the input fields to get the user login details.

User Login Form Screenshot

This is the screenshot of the welcome message. Once logged-in, then the user will see this response in the browser.

This view will show a welcome message by addressing the logged-in user. It also has a link to logout as shown below.

User Dashboard Output

Download

Comments to “PHP Login Script with Session”

  • ali says:

    Thanks for sharing , it helped me a lot in my little project.

  • swapnil says:

    can you pls share the sql file with download.
    thx

    • Gideon Birimuye says:

      Hi swapnil, hope you are doing great.The sql file below might be of help to you, i exported it using phpMyAdmin. You can copy it and save it as an sql file using any software (notepad, notepad++,Dreamweaver) any that you feel comfortable with and then import it in phpMyAdmin and then play with vincy’s scripts. Have fun.

      — phpMyAdmin SQL Dump
      — version 3.2.0.1
      http://www.phpmyadmin.net

      — Host: localhost
      — Generation Time: Dec 22, 2013 at 06:52 AM
      — Server version: 5.1.36
      — PHP Version: 5.3.0

      SET SQL_MODE=”NO_AUTO_VALUE_ON_ZERO”;


      — Database: `login_script`

      — ——————————————————–


      — Table structure for table `users`

      CREATE TABLE IF NOT EXISTS `users` (
      `user_id` int(11) NOT NULL AUTO_INCREMENT,
      `user_name` varchar(10) NOT NULL,
      `password` varchar(3) NOT NULL,
      PRIMARY KEY (`user_id`)
      ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;


      — Dumping data for table `users`

      INSERT INTO `users` (`user_id`, `user_name`, `password`) VALUES
      (1, ‘Gideon’, ‘fox’);

      • Haris says:

        what is username and password to login?

      • Vincy says:

        Hari,

        I assume you are asking for the username and password for your local-database. By default, generally it is “root” and empty password.

    • Gideon Birimuye says:

      Swapnil remember i changed the name of the database to login_script. Keep in touch if you need more help.

  • Kumara says:

    Great work!

  • Wan says:

    Hi, the page is not redirect to dashboard.php?

    Thanks

  • Wan says:

    My fault, I am missing a row in SQL. it should be OK now.. :)

  • Akinsola says:

    good work Vincy,
    Thank you soo much

  • kevin says:

    hi,,,tnx alot…but still i have a problem in connecting into the database,,,the message INVALID will always pomp up…how can you advice me?

    • Vincy says:

      Hi Kevin,

      $conn = mysql_connect(“localhost”,”root”,””);

      Replace host,username and password specified for mysql_connect(), with your server config.

  • Lee says:

    Love the tutorial, I have a problem though. When I click submit it takes me to the User Dashboard but it is a blank page that just says ‘User Dashboard’ at the top.

  • Kalidoss says:

    Hi
    Am Kalidoss from India.
    this article very useful for me.. Thank you so much.Am always expecting your new update.

  • ragu says:

    logout session not work on mine for some reason i run the code as downloaded form here so i dont know why its not working. i can login in fine but its the login out thats not working

  • arun says:

    hello
    i have tried this code
    but i am getting following warnings
    1. message is not defined in
    2.Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in

    • Vincy says:

      Hi Arun,

      @Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in

      This is because of query failure. Before executing this query, ensure that you have users table with respective columns in database, as specified in code.

      @message is not defined in

      We have to define $message before we use. Otherwise, we need to check $message whether it is set or not. For example,
      if(isset($message)) echo $message;

  • Gideon Birimuye says:

    Vincy thanks for the sharing, it was really helpful. keep it up.

  • saiful islam says:

    i am know of ur form mining but i can’t show error message in the login page($messgae variable data), when i run the login form with wrong information but doesn’t show the message. The message area show all time in this message(Notice: Undefined variable: message in D:DIUwampwwwphptotal_loginIndia_loginformindex.php on line 9 ). How to show check validation message in the login page. Please suggest me. Thanks

  • sumit says:

    Hi vincy.
    This tutorial helped me alot .
    I would now like to know how do we display the name of the user logged in by hiding the login or signup button and they should reappear when the used loggs out. I have gone through many sites but could not understand.
    Would u plz write a code that would help me?

    • Vincy says:

      Hi Sumit,

      To display logged in username instead of login button,

      if($_SESSTION[“username”]) {
      echo $_SESSTION[“username”];
      } else {
      // display login button
      }

      Make sure, you have stored logged in user name into a session variable while login.

  • vhinzlloyd says:

    hi ,,thank u very much,,but i still have problem..ive noticed when i logged out,,and press back it will got an error,,like this Notice: Undefined index: user_name in C:\xampp\htdocs\experiment\samplelogin\user_dashboard.php on line 18
    .please help

    • Vincy says:

      Hi vhinzlloyd,

      If you check user_name session like,

      if(isset($_SESSION[“user_name”])) {

      instead of

      if($_SESSION[“user_name”]) {

      you can avoid this error notice.

  • Sjoerd says:

    I keep getting ‘Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in x at line x’

    How can I fix this?

  • Vincy says:

    Hi Michal,

    Thank you for the comment.

    This tutorial is just to explain login to storing user credentials into session.

    We can enhance this code by adding,

    • Validation to avoid SQL injection.
    • Javascript/Server side validation to prevent HTML code or other escape sequences.
    • We can log repeated invalid login attempts to stop anonymous by IP address.

    and etc. to avoid the security risks. But it will enlarge the code and loose the focus on topic.

    Security is more important and let us have separate tutorials to learn how to safeguard from security risk.

    Thank you for raising this point.

  • carlos says:

    hi and thanks for the article it is simple and easy-to-understand
    but i have a question here in the login redirect part line #4

    if(count($_POST)>0)

    is it possible to use isset instead of count ?? thanks again.

  • Himmat says:

    THANKS

  • banu says:

    hi,
    can yu pls help me wid dis error
    ” Notice: Undefined index: user_name in C:\xampp\htdocs\b\try\application\views\scripts\index\login.php on line 16 “

  • Rich says:

    Hi, im having trouble with session variable is not passing to the next page,
    The code i have is very similar to yours except a few security tweaks
    heres my bits n pieces

    //Register session variable after db check on authlogin.php page –
    ———————————
    $_SESSION[‘u_name’] = “myusername”;

    header(“location:summary.php”);
    }
    else {
    echo “Wrong Username or Password”;
    }
    ———————————

    And to validate on the account summary page –
    ———————————
    if($_SESSTION[“u_name”]) {
    echo $_SESSTION[“u_name”];
    } else {
    header(“location:index.php”);
    }
    ———————————

    Any help is much aprecciated :D

  • ron says:

    I want ask 1 question..how to select multiple table from single database to login..?example table group1,group2 and group3.so what php code for this?.

  • jorx says:

    hi these is the error i’m getting

    Notice: Undefined index: user_name in D:\xampp\htdocs\login\login.php on line 14

  • Jayamaha says:

    Thank u so much …

  • anu says:

    thx it was nicely xplained.but im having a problem with logout.
    when i logged out and press back button it will again redirect to the user’s account page(Previous Logged in page);
    this is the logged out code

  • David says:

    Thanks, cool stuff keep it up!

  • ganesh says:

    Thanks for tutorial…its great.

  • Mincy Varghese says:

    Can anyone help me ?.. I need to store all login details in a database.. somebody plz share me the coding if you have

  • ganesh says:

    Nice article for beginners like me.

  • Aggrey says:

    Pretty ideas, The guide saved me out. Oh,Thx alot.

  • PHP Training says:

    This is one of the best place to learn about web designing especially php and mysql.

  • PHP Training says:

    This is one of the best blog for developing login form using script. thanks vincy.
    by mathivel (php developer)

  • sakura says:

    thanks it is very helpful and informative… =D

  • Maffix says:

    Thanks for sharing the wonderful made code.

    It saves my day..

    Chers

Leave a Reply to vhinzlloyd Cancel reply

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

↑ Back to Top

Share this Article