PHP Simple Login and Registration Script
This is a simple login and registration system in PHP and MySQL. A new user registers with a name, email and password. After that the user can log in, see protected pages, and log out. The user is remembered with a PHP session (read PHP Session to understand it).
The code is short, but it follows the important security rules: passwords are saved as hashes with password_hash(), every database query is a prepared statement, and all printed values are escaped.
Files of the script
| File | Purpose |
|---|---|
| database.sql | Creates the database and the users table |
| db-config.php | Connects PHP with MySQL |
| register.php | Registration form and the code to save a new user |
| login.php | Login form and the code to check the email and password |
| dashboard.php | A protected page, only for logged in users |
| logout.php | Destroys the session and logs the user out |
Create a folder, for example login-script, inside the folder of your local server (htdocs in XAMPP) and save all the files in it. Run http://localhost/login-script/register.php.
1) database.sql
Run these queries in phpMyAdmin (or import the file).
CREATE DATABASE IF NOT EXISTS register_login_db
CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE register_login_db;
CREATE TABLE IF NOT EXISTS users (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(150) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
The password column is VARCHAR(255), because a password hash is long. The email is UNIQUE, so the same email can not register two times.
2) db-config.php
<?php
// Show database errors as exceptions (do not display them on a live site)
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$conn = new mysqli("localhost", "root", "", "register_login_db");
$conn->set_charset("utf8mb4");
3) register.php
<?php
session_start();
require_once "db-config.php";
$message = "";
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$name = trim($_POST["name"] ?? "");
$email = filter_var(trim($_POST["email"] ?? ""), FILTER_VALIDATE_EMAIL);
$password = $_POST["password"] ?? "";
if ($name === "" || !$email || strlen($password) < 8) {
$message = "Enter your name, a valid email and a password of at least 8 characters.";
} else {
// Is the email already registered?
$stmt = $conn->prepare("SELECT id FROM users WHERE email = ?");
$stmt->bind_param("s", $email);
$stmt->execute();
if ($stmt->get_result()->num_rows > 0) {
$message = "This email is already registered.";
} else {
$hash = password_hash($password, PASSWORD_DEFAULT);
$insert = $conn->prepare("INSERT INTO users (name, email, password) VALUES (?, ?, ?)");
$insert->bind_param("sss", $name, $email, $hash);
$insert->execute();
$message = "Registration successful. You can login now.";
}
}
}
?>
<h2>Register</h2>
<p><?php echo htmlspecialchars($message); ?></p>
<form method="post">
<p>Name: <input type="text" name="name" value="<?php echo htmlspecialchars($_POST["name"] ?? ""); ?>"></p>
<p>Email: <input type="email" name="email" value="<?php echo htmlspecialchars($_POST["email"] ?? ""); ?>"></p>
<p>Password: <input type="password" name="password"></p>
<p><button type="submit">Register</button></p>
</form>
<p><a href="login.php">Already have an account? Login</a></p>
4) login.php
<?php
session_start();
require_once "db-config.php";
$message = "";
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$email = trim($_POST["email"] ?? "");
$password = $_POST["password"] ?? "";
$stmt = $conn->prepare("SELECT id, name, password FROM users WHERE email = ?");
$stmt->bind_param("s", $email);
$stmt->execute();
$user = $stmt->get_result()->fetch_assoc();
if ($user && password_verify($password, $user["password"])) {
session_regenerate_id(true); // new session id after login
$_SESSION["user_id"] = $user["id"];
$_SESSION["user_name"] = $user["name"];
header("Location: dashboard.php");
exit;
}
// Same message for a wrong email and a wrong password
$message = "Wrong email or password.";
}
?>
<h2>Login</h2>
<p><?php echo htmlspecialchars($message); ?></p>
<form method="post">
<p>Email: <input type="email" name="email"></p>
<p>Password: <input type="password" name="password"></p>
<p><button type="submit">Login</button></p>
</form>
<p><a href="register.php">Create an account</a></p>
5) dashboard.php (protected page)
Add the same check at the top of every page that only logged in users can see.
<?php
session_start();
if (empty($_SESSION["user_id"])) {
header("Location: login.php");
exit;
}
?>
<h2>Welcome, <?php echo htmlspecialchars($_SESSION["user_name"]); ?></h2>
<p>This page is only for logged in users.</p>
<p><a href="logout.php">Logout</a></p>
6) logout.php
<?php
session_start();
$_SESSION = [];
session_destroy();
header("Location: login.php");
exit;
How it works
- Registration: the data is validated, the email is checked for duplicates, the password is turned into a hash and the user is inserted with a prepared statement.
- Login: the user row is found by the email.
password_verify()compares the typed password with the saved hash. On success the user id is saved in the session. - Protected pages: every protected page checks
$_SESSION["user_id"]. Without it, the visitor is sent to the login page. - Logout: the session data is removed and the session is destroyed.
Before you use it on a live website
- Use HTTPS, and set the session cookie as secure, httponly and SameSite. See how to store passwords securely and PHP Security Tips.
- Add a CSRF token to both forms: What is CSRF?.
- Limit the login attempts (for example lock for 15 minutes after 5 wrong tries), to stop password guessing.
- Add email verification and a password reset feature, and use a dedicated MySQL user (not root) with limited rights.
- Do not show database errors to visitors.
Want a “Remember me” option? See PHP Login with Remember me using Cookies.
| Tutorials |
|---|
| No Content Found. |
| Exercises & Assignments |
|---|
| No Content Found. |
| Interview Questions & Answers |
|---|
| No Content Found. |