Debremarkos poly tecnic college
Web development and database administration level-4
Asignmnt 1
Weight 30%
Develop a registration system using PHP involves several key components, including user
interface (HTML), server-side logic (PHP), and a database (MySQL is the most common
choice). Here's a comprehensive breakdown of how to create one, covering the essential steps
and best practices:
Core Components:
1. HTML Forms: For users to input their registration details.
2. PHP Script: To process the form data, validate it, and interact with the database.
3. MySQL Database: To store user information (username, email, password, etc.).
4. CSS (Optional but Recommended): For styling the forms and pages.
5. JavaScript (Optional for Client-Side Validation): To provide immediate feedback to
users before form submission.
Steps to Build a Registration System:
Step 1: Database Setup (MySQL)
First, you need a database and a table to store user information.
Database Name: registration_db (or whatever you prefer)
Table Name: users
Here's the SQL query to create the users table:
CREATE DATABASE IF NOT EXISTS registration_db;
USE registration_db;
CREATE TABLE IF NOT EXISTS users (
id INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(100) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
<?php
$servername = "localhost"; // Usually "localhost" for local development
$username = "root"; // Your MySQL username
$password = ""; // Your MySQL password
$dbname = "registration_db"; // The database you created
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
// Optional: Set character set to UTF-8
$conn->set_charset("utf8");
?>
<?php
include 'db_connection.php'; // Include your database connection file
$username = $email = $password = $confirm_password = "";
$username_err = $email_err = $password_err = $confirm_password_err = "";
$registration_success = "";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// 1. Validate Username
if (empty(trim($_POST["username"]))) {
$username_err = "Please enter a username.";
} else {
// Check if username already exists
$sql = "SELECT id FROM users WHERE username = ?";
if ($stmt = $conn->prepare($sql)) {
$stmt->bind_param("s", $param_username);
$param_username = trim($_POST["username"]);
if ($stmt->execute()) {
$stmt->store_result();
if ($stmt->num_rows == 1) {
$username_err = "This username is already taken.";
} else {
$username = trim($_POST["username"]);
}
} else {
echo "Oops! Something went wrong. Please try again later.";
$stmt->close();
// 2. Validate Email
if (empty(trim($_POST["email"]))) {
$email_err = "Please enter an email address.";
} elseif (!filter_var(trim($_POST["email"]), FILTER_VALIDATE_EMAIL)) {
$email_err = "Invalid email format.";
} else {
// Check if email already exists
$sql = "SELECT id FROM users WHERE email = ?";
if ($stmt = $conn->prepare($sql)) {
$stmt->bind_param("s", $param_email);
$param_email = trim($_POST["email"]);
if ($stmt->execute()) {
$stmt->store_result();
if ($stmt->num_rows == 1) {
$email_err = "This email is already registered.";
} else {
$email = trim($_POST["email"]);
} else {
echo "Oops! Something went wrong. Please try again later.";
$stmt->close();
// 3. Validate Password
if (empty(trim($_POST["password"]))) {
$password_err = "Please enter a password.";
} elseif (strlen(trim($_POST["password"])) < 6) {
$password_err = "Password must have at least 6 characters.";
} else {
$password = trim($_POST["password"]);
// 4. Validate Confirm Password
if (empty(trim($_POST["confirm_password"]))) {
$confirm_password_err = "Please confirm password.";
} else {
$confirm_password = trim($_POST["confirm_password"]);
if (empty($password_err) && ($password != $confirm_password)) {
$confirm_password_err = "Password did not match.";
// If no errors, proceed to insert into database
if (empty($username_err) && empty($email_err) && empty($password_err) &&
empty($confirm_password_err)) {
$sql = "INSERT INTO users (username, email, password) VALUES (?, ?, ?)";
if ($stmt = $conn->prepare($sql)) {
$stmt->bind_param("sss", $param_username, $param_email, $param_password);
// Hash the password for security
$param_password = password_hash($password, PASSWORD_DEFAULT);
$param_username = $username;
$param_email = $email;
if ($stmt->execute()) {
$registration_success = "Registration successful! You can now <a
href='login.php'>login</a>.";
// Clear form fields after successful registration
$username = $email = $password = $confirm_password = "";
} else {
echo "Something went wrong. Please try again later.";
$stmt->close() }
$conn->close(); // Close connection after processing
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>User Registration</title>
<style>
body { font-family: Arial, sans-serif; background-color: #f4f4f4; display: flex; justify-
content: center; align-items: center; min-height: 100vh; margin: 0; }
.container { background-color: #fff; padding: 30px; border-radius: 8px; box-shadow: 0 0
10px rgba(0, 0, 0, 0.1); width: 400px; }
h2 { text-align: center; margin-bottom: 20px; color: #333; }
.form-group { margin-bottom: 15px; }
label { display: block; margin-bottom: 5px; color: #555; }
input[type="text"], input[type="email"], input[type="password"] {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
box-sizing: border-box; /* Ensures padding doesn't increase width */
.error { color: red; font-size: 0.9em; margin-top: 5px; }
.success { color: green; font-size: 1em; text-align: center; margin-bottom: 15px; }
.btn {
background-color: #007bff;
color: white;
padding: 10px 15px;
border: none;
border-radius: 4px;
cursor: pointer;
width: 100%;
font-size: 16px;
.btn:hover { background-color: #0056b3; }
.link { text-align: center; margin-top: 15px; }
.link a { color: #007bff; text-decoration: none; }
.link a:hover { text-decoration: underline; }
</style>
</head>
<body>
<div class="container">
<h2>Register</h2>
<?php if (!empty($registration_success)): ?>
<div class="success"><?php echo $registration_success; ?></div>
<?php endif; ?>
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>"
method="post">
<div class="form-group">
<label for="username">Username:</label>
<input type="text" id="username" name="username" value="<?php echo
htmlspecialchars($username); ?>">
<span class="error"><?php echo $username_err; ?></span>
</div>
<div class="form-group">
<label for="email">Email:</label>
<input type="email" id="email" name="email" value="<?php echo
htmlspecialchars($email); ?>">
<span class="error"><?php echo $email_err; ?></span>
</div>
<div class="form-group">
<label for="password">Password:</label>
<input type="password" id="password" name="password" value="<?php echo
htmlspecialchars($password); ?>">
<span class="error"><?php echo $password_err; ?></span>
</div>
<div class="form-group">
<label for="confirm_password">Confirm Password:</label>
<input type="password" id="confirm_password" name="confirm_password"
value="<?php echo htmlspecialchars($confirm_password); ?>">
<span class="error"><?php echo $confirm_password_err; ?></span>
</div>
<div class="form-group">
<input type="submit" class="btn" value="Register">
</div>
<div class="link">
Already have an account? <a href="login.php">Login here</a>.
</div>
</form>
</div>
</body>
</html>
Explanation of register.php:
1. Include db_connection.php: Establishes the database connection.
2. Initialize Variables: Sets up variables to store form data and error messages.
3. $_SERVER["REQUEST_METHOD"] == "POST": Checks if the form has been submitted.
4. Input Validation:
o trim(): Removes whitespace from the beginning and end of strings.
o empty(): Checks if a variable is empty.
o filter_var(..., FILTER_VALIDATE_EMAIL): Validates email format.
o Server-Side Validation: This is crucial. It checks for:
Empty fields.
Minimum password length.
Password and confirm password match.
Unique username and email (by querying the database).
5. Password Hashing (password_hash()): Absolutely essential for security! Never store
plain text passwords in your database. password_hash() uses a strong, one-way hashing
algorithm.
6. Prepared Statements ($conn->prepare() and bind_param()): Crucial for
preventing SQL Injection attacks! This separates the SQL query from the data, making
it impossible for malicious code to be injected.
7. Data Insertion: If all validations pass, the user data (with the hashed password) is
inserted into the users table.
8. HTML Form:
o action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>":
Submits the form back to the same page. htmlspecialchars() prevents XSS
vulnerabilities.
o method="post": Sends form data securely.
o Error messages are displayed next to their respective input fields using <span
class="error">.
o value="<?php echo htmlspecialchars($username); ?>": This retains the
user's input in the form fields after a submission error, improving user experience.
Step 4: Login System (login.php - Optional but Recommended)
A registration system is usually accompanied by a login system. Here's a basic login.php
example:
<?php
session_start(); // Start the session
include 'db_connection.php';
$username = $password = "";
$username_err = $password_err = "";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// 1. Validate Username
if (empty(trim($_POST["username"]))) {
$username_err = "Please enter username.";
} else {
$username = trim($_POST["username"]);
// 2. Validate Password
if (empty(trim($_POST["password"]))) {
$password_err = "Please enter your password.";
} else {
$password = trim($_POST["password"]);
// If no validation errors, attempt to login
if (empty($username_err) && empty($password_err)) {
$sql = "SELECT id, username, password FROM users WHERE username = ?";
if ($stmt = $conn->prepare($sql)) {
$stmt->bind_param("s", $param_username);
$param_username = $username;
if ($stmt->execute()) {
$stmt->store_result();
if ($stmt->num_rows == 1) {
$stmt->bind_result($id, $username, $hashed_password);
if ($stmt->fetch()) {
if (password_verify($password, $hashed_password)) {
// Password is correct, start a new session
$_SESSION["loggedin"] = true;
$_SESSION["id"] = $id;
$_SESSION["username"] = $username;
// Redirect user to welcome page
header("location: welcome.php");
exit;
} else {
$password_err = "The password you entered was not valid.";
} else {
$username_err = "No account found with that username.";
}
} else {
echo "Oops! Something went wrong. Please try again later.";
$stmt->close();
$conn->close();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>User Login</title>
<style>
/* (Add the same CSS as in register.php or link a common CSS file) */
body { font-family: Arial, sans-serif; background-color: #f4f4f4; display: flex; justify-
content: center; align-items: center; min-height: 100vh; margin: 0; }
.container { background-color: #fff; padding: 30px; border-radius: 8px; box-shadow: 0 0
10px rgba(0, 0, 0, 0.1); width: 400px; }
h2 { text-align: center; margin-bottom: 20px; color: #333; }
.form-group { margin-bottom: 15px; }
label { display: block; margin-bottom: 5px; color: #555; }
input[type="text"], input[type="password"] {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
box-sizing: border-box;
.error { color: red; font-size: 0.9em; margin-top: 5px; }
.btn {
background-color: #007bff;
color: white;
padding: 10px 15px;
border: none;
border-radius: 4px;
cursor: pointer;
width: 100%;
font-size: 16px;
.btn:hover { background-color: #0056b3; }
.link { text-align: center; margin-top: 15px; }
.link a { color: #007bff; text-decoration: none; }
.link a:hover { text-decoration: underline; }
</style>
</head>
<body>
<div class="container">
<h2>Login</h2>
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>"
method="post">
<div class="form-group">
<label for="username">Username:</label>
<input type="text" id="username" name="username" value="<?php echo
htmlspecialchars($username); ?>">
<span class="error"><?php echo $username_err; ?></span>
</div>
<div class="form-group">
<label for="password">Password:</label>
<input type="password" id="password" name="password">
<span class="error"><?php echo $password_err; ?></span>
</div>
<div class="form-group">
<input type="submit" class="btn" value="Login">
</div>
<div class="link">
Don't have an account? <a href="register.php">Register now</a>.
</div>
</form>
</div>
</body>
</html>
4. Styling with CSS (style.css)
Create a style.css file to make your form look good.
```css
body { font-family: Arial, sans-serif;
background-color: #f4f4f4;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh; margin: 0;
.registration-container { background-color: #fff;
padding: 30px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
width: 100%;
max-width: 400px;
box-sizing: border-box;
}
h2
text-align: center; margin-bottom: 20px; color: #333;
.form-group { margin-bottom: 15px;
.form-group label { display: block;
margin-bottom: 5px; color: #555; }
.form-control { width: 100%;
padding: 10px; border: 1px solid #ddd;
border-radius: 4px;
box-sizing: border-box;
/* Ensures padding doesn't increase total width */ }
.form-group.has-error .form-control { border-color: #dc3545;
/* Red border for errors */ }
.help-block { color: #dc3545;
/* Red text for error messages */
font-size: 0.9em; margin-top: 5px; display: block;
.btn { background-color: #007bff;
color: white;
padding: 12px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
width: 100%;
font-size: 16px;
transition: background-color 0.3s ease;
.btn:hover
background-color: #0056b3;
p { text-align: center; margin-top: 20px;
p a { color: #007bff; text-decoration: none;
p a:hover { text-decoration: underline;
Explanation of login.php:
1. session_start(): Starts a PHP session to store user login status.
2. Retrieve User from Database: Queries the database for the provided username.
3. password_verify(): Compares the user-provided password with the hashed password
from the database. This function securely verifies the password without needing to
unhash it.
4. Session Variables: If login is successful, relevant user information (ID, username) is
stored in $_SESSION variables.
5. Redirection: Redirects the user to a welcome.php page after successful login.
Step 5: Welcome Page (welcome.php - Optional)
<?php
session_start();
// Check if the user is logged in, otherwise redirect to login page
if (!isset($_SESSION["loggedin"]) || $_SESSION["loggedin"] !== true) {
header("location: login.php");
exit;
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Welcome</title>
<style>
body { font-family: Arial, sans-serif; background-color: #f4f4f4; display: flex; justify-
content: center; align-items: center; min-height: 100vh; margin: 0; text-align: center; }
.container { background-color: #fff; padding: 30px; border-radius: 8px; box-shadow: 0 0
10px rgba(0, 0, 0, 0.1); width: 400px; }
h2 { color: #333; margin-bottom: 20px; }
p { color: #555; margin-bottom: 20px; }
.logout-btn {
background-color: #dc3545;
color: white;
padding: 10px 15px;
border: none;
border-radius: 4px;
cursor: pointer;
text-decoration: none; /* For the anchor tag */
display: inline-block; /* For the anchor tag */
.logout-btn:hover { background-color: #c82333; }
</style>
</head>
<body>
<div class="container">
<h2>Welcome, <?php echo htmlspecialchars($_SESSION["username"]); ?>!</h2>
<p>You have successfully logged in.</p>
<p>
<a href="logout.php" class="logout-btn">Sign Out</a>
</p>
</div>
</body>
</html>
Step 6: Logout Script (logout.php - Optional)
<?php
session_start();
// Unset all of the session variables
$_SESSION = array();
// Destroy the session.
session_destroy();
// Redirect to login page
header("location: login.php");
exit;
?>
How to Run the System:
1. XAMPP/WAMP/MAMP: Install a local server environment (XAMPP, WAMP, or
MAMP) which provides Apache, MySQL, and PHP.
2. Database: Start MySQL and create the registration_db database and users table
using the SQL query provided in Step 1. You can use phpMyAdmin (usually included
with XAMPP/WAMP/MAMP) for this.
3. Place Files: Save all the PHP files (db_connection.php, register.php, login.php,
welcome.php, logout.php) in your web server's document root (e.g., htdocs for
XAMPP).
4. Access: Open your web browser and navigate to http://localhost/register.php (or
whatever folder you placed them in).
Key Security Considerations:
Password Hashing: Always use password_hash() and password_verify(). Never
store plain text passwords.
Prepared Statements: Essential to prevent SQL injection.
Input Validation: Validate all user input on the server-side to prevent malicious data
from entering your database. Client-side validation (using JavaScript) is good for user
experience but can be bypassed.
HTTPS: For production environments, use HTTPS to encrypt data transmitted between
the client and server.
Error Reporting: In a production environment, disable display_errors in your
php.ini and log errors to a file instead.
Session Security: Regenerate session IDs after login (session_regenerate_id(true))
to prevent session fixation.
Rate Limiting: Implement measures to prevent brute-force attacks on login.