After visiting this forum (and others) I have been seeing people having problems writing a login/registration system in PHP. So I decided to write a very simple one, it only has four attributes/properties: id, username, password, date_added. I just want to clarify one thing, when I said PDO was written in OOP Style I meant the code that interacts between PHP and MySQL.
I know it works for I have tested out. It is heavily commented, so this will be it with my jabbering about it. ;D
filename: common.inc.php in a folder called includes:
[php]<?php
//Start session
session_start();
// create an user $_SESSION array:
$_SESSION[‘user’] = NULL;
// Set error message to Null
$errMsg = NULL;
// Create the database connection as a PDO object:
try {
$db_options = array(
PDO::ATTR_EMULATE_PREPARES => false // important! use actual prepared statements (default: emulate prepared statements)
, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION // throw exceptions on errors (default: stay silent)
, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC // fetch associative arrays (default: mixed arrays)
);
$pdo = new PDO('mysql:host=localhost;dbname=demo_login_system;charset=utf8', 'root', 'your_password', $db_options);
} catch (PDOException $e) { // Report the Error!
$errMsg = "<p>Something is not right, check your php.ini settings or code</p>";
}
// A nice little function that sanitizes the data output:
function html_escape($raw_input) {
return htmlspecialchars($raw_input, ENT_QUOTES | ENT_HTML401, ‘UTF-8’); // important! don’t forget to specify ENT_QUOTES and the correct encoding
} [/php]
filename: register.php located in the root directory.
[php]<?php
/*
********* TABLE Structure *********
CREATE TABLE IF NOT EXISTS users
(
id
int(11) NOT NULL AUTO_INCREMENT,
username
varchar(30) NOT NULL,
password
char(60) NOT NULL,
date_added
timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id
)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;
*/
// common.inc.php file contains required
// database connection & initialization info:
require ‘includes/common.inc.php’;
// A nice password hashing library for PHP 5
// Find it here: https://github.com/ircmaxell/password_compat/blob/master/lib/password.php
// Read the Documentation for further help:
// NOTE: if you’re not using PHP 5, there are plenty of
// other good password hashing libraries out there —> JUST GOOGLE IT!
require ‘includes/password.inc.php’;
// Check to see if user has submitted form:
if (isset($_POST[‘action’]) && $_POST[‘action’] == ‘register’) {
// Grab the user's input from form:
$username = $_POST['username'];
$password = $_POST['password'];
// Using Regex to check username:
if (preg_match("/^[0-9a-zA-Z_]{5,}$/", $username) === 0) {
$errMsg = '<p>Username must be bigger that 5 chars and contain only digits, letters and underscore<p>';
}
// Using Regex to check password:
if (preg_match("/^.*(?=.{8,})(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z]).*$/", $password) === 0) {
$errMsg .= '<p>Password must be at least 8 characters, and must contain at least one lower case letter, one upper case letter and one digit.</p>';
}
// Function to check if username is available:
function isUsernameAvailable($username, $pdo) {
// The PDO Query:
$query = "
SELECT
1
FROM users
WHERE
username = :username1
";
// The prepared property/attribute:
$query_params = array(
':username1' => $username
);
// These two statements run the query against your database table.
$stmt = $pdo->prepare($query);
$result = $stmt->execute($query_params);
// The fetch() method returns an array representing the "next" row from
// the selected results, or false if there are no more rows to fetch.
return $row = $stmt->fetch();
// If a row was returned, then we know a matching username was found in
// the database already and we should return a boolean value back.
}
// Check to see if username is available:
$result = isUsernameAvailable($username, $pdo);
// If username is taken then assign to $errMsg:
if ($result) {
$errMsg .= '<p>Username: ' . $username . ' is already taken.</p>';
}
// Hash the password - See above for details:
$password = password_hash($password, PASSWORD_BCRYPT, array("cost" => 15));
// Store user's credentials, if form data is validated:
if(!$errMsg) {
// Using prepared statements:
$query = 'INSERT INTO users ( username, password ) VALUES ( :username, :password )';
$stmt = $pdo->prepare($query);
$result = $stmt->execute(array(':username' => $username, ':password' => $password));
$errMsg = 'You have successfully registered to our great website!';
}
}
?>
Registration Page
'; ?>Username:
Password:
filename: login.php located in the root directory.
[php]<?php
// common.inc.php file contains required
// database connection initialization info:
require ‘includes/common.inc.php’;
// A nice password hashing library for PHP 5
// Find it here: https://github.com/ircmaxell/password_compat/blob/master/lib/password.php
// Read the Documentation for further help:
require ‘includes/password.inc.php’;
if (isset($_POST[‘action’]) && $_POST[‘action’] == ‘login’) {
// This query retreives the user's information from the database using
// their username.
$query = '
SELECT
id,
username,
password,
DATE_FORMAT(date_added, "%e %M %Y") as date_added
FROM users
WHERE
username = :username
';
// The parameter values
$query_params = array(
':username' => $_POST['username']
);
try
{
// Execute the query against the database
$stmt = $pdo->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex)
{
// Note: On a production website, you should not output $ex->getMessage().
// It may provide an attacker with helpful information about your code.
die("Failed to run query: " . $ex->getMessage());
}
// This variable tells us whether the user has successfully logged in or not.
// We initialize it to false, assuming they have not.
// If we determine that they have entered the right details, then we switch it to true.
$login_ok = false;
// Retrieve the user data from the database. If $row is false, then the username
// they entered is not registered.
$row = $stmt->fetch();
if($row)
{
// Verify Stored Hashed Password:
$result = password_verify($_POST['password'], $row['password']);
if ($result) {
$login_ok = true;
} else {
$errMsg = '<p>Your credientials do not match!</p>';
}
}
// If login is OK:
if ($login_ok) {
// It's not wise to store the password in $_SESSION:
unset($row['password']);
// This stores the user's data into the session at the index 'user'.
// We will check this index on the private members-only page to determine whether
// or not the user is logged in. We can also use it to retrieve
// the user's details.
$_SESSION['user'] = $row;
// The following output is just to prove that it works:
echo '<pre>';
print_r($_SESSION);
echo '</pre>';
// Redirect the user to the private members-only page.
//header("Location: admin.php");
//die("Redirecting to: admin.php");
}
}
/*
- This was just to help people who are just getting started
- learning how to program in the PHP Language. The PDO portion
- is written in Object-Oriented Style, but this doesn’t mean
- that you now know OOP or that you have to use it. It’s pretty
- straight forward in my opinion. I have tested this out, but I make
- no guarantees that it works 100 percent and it diffentely needs
- updating/styling. However, that is up to you and besides it’s
- a good way to learn PHP.
*/
?>
Login Page:
'; ?>Username:
Password:
For further help and understanding about PHP go to php.net…