From Scratch to Inbox: Develop a Gmail-Like Email App Using PHP & MySQL
how to build a simplified version of Gmail
using PHP and MySQL, focusing on core email functionalities such as
registration, login, compose, inbox, and view messages.
🔧 Tools Required:
Tool |
Purpose |
XAMPP/WAMP/LAMP |
Local server with Apache, PHP, MySQL |
Code Editor |
VS Code. |
Web Browser |
Chrome, Firefox, etc. |
📁 Project Structure
(Example)
mymail/
│
├── db/ ← Database connection
│
└── db.php
│
├── auth/
│
├── register.php
│
├── logout.php
│
└── login.php
│
├── include/
│
├── header.php
│
├── sidebar.php
│
└── footer.php
│
├── dashboard.php ← View dashboard
├── inbox.php ← View inbox messages
├── compose.php ← Compose new message
├── send.php ← Handle sending message
├── view.php ← View specific message
├── logout.php
├── style.css
└── index.php ← Redirect or login page
🧩 STEP 1: Setup XAMPP &
Project Folder
1.
Install
XAMPP.
2.
Create
folder gmail_clone in htdocs.
3.
Start
Apache and MySQL from XAMPP Control Panel.
4.
Open
http://localhost/phpmyadmin.
🧩 STEP 2: Create MySQL
Database
Create Database
CREATE DATABASE mymail;
USE mymail;
Create Tables
1. users Table
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
email VARCHAR(100) UNIQUE,
password VARCHAR(255),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
2. messages Table
CREATE TABLE messages (
id INT AUTO_INCREMENT PRIMARY KEY,
sender_id INT,
receiver_email VARCHAR(100),
subject VARCHAR(255),
body TEXT,
sent_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (sender_id) REFERENCES users(id)
);
mymail.sql
CREATE DATABASE gmail_clone;
USE gmail_clone;
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
email VARCHAR(100) UNIQUE,
password VARCHAR(255),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE messages (
id INT AUTO_INCREMENT PRIMARY KEY,
sender_id INT,
receiver_email VARCHAR(100),
subject VARCHAR(255),
body TEXT,
sent_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (sender_id) REFERENCES users(id)
);
🧩 STEP 3: Database
Connection (db/db.php)
<?php
$host = "localhost";
$user = "root";
$pass = "";
$db = "gmail_clone";
$conn = new mysqli($host, $user, $pass,
$db);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
?>
🧩 STEP 5: Landing Page (index.php)
<?php
session_start();
if (isset($_SESSION['user_id'])) {
header("Location:
inbox.php");
exit();
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>MyMail - Home</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body {
background: linear-gradient(135deg, #e0f7fa, #e1f5fe);
height: 100vh;
margin: 0;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
.logo {
font-size: 64px;
font-weight: bold;
letter-spacing: 1px;
animation: zoomIn 1s ease-in-out;
}
@keyframes zoomIn {
0% { transform: scale(0.8); opacity: 0; }
100% { transform: scale(1); opacity: 1; }
}
.tagline {
font-size: 20px;
color: #555;
margin-top: 10px;
}
.btn-group {
margin-top: 40px;
}
.btn-custom {
padding: 10px 25px;
font-size: 18px;
transition: all 0.3s ease-in-out;
}
.btn-custom:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}
</style>
</head>
<body>
<div class="logo">
<span style="color:#4285F4">M</span>
<span style="color:#DB4437">y</span>
<span style="color:#F4B400">M</span>
<span style="color:#0F9D58">a</span>
<span style="color:#4285F4">i</span>
<span style="color:#DB4437">l</span>
</div>
<div class="tagline">Simple. Secure. Fast Communication.</div>
<div class="btn-group">
<a href="auth/login.php" class="btn btn-primary
me-3 btn-custom">Sign In</a>
<a href="auth/register.php" class="btn
btn-outline-dark btn-custom">Sign Up</a>
</div>
</body>
</html>
🧩 STEP 5: User Registration
(auth/register.php)
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
include '../db/db.php';
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$name =
mysqli_real_escape_string($conn, $_POST['name']);
$email =
mysqli_real_escape_string($conn, $_POST['email']);
$password = password_hash($_POST['password'], PASSWORD_DEFAULT);
// Check if email already exists
$check = mysqli_query($conn, "SELECT * FROM users WHERE email = '$email'");
if (mysqli_num_rows($check) > 0) {
$error = "Email already
exists.";
} else {
$query = "INSERT INTO users(name, email, password) VALUES ('$name', '$email',
'$password')";
if (mysqli_query($conn,
$query)) {
$success = "Registered
successfully. <a href='login.php'>Login here</a>";
} else {
$error
= "Something went
wrong. Please try again.";
}
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Register</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
</head>
<body class="bg-light">
<div class="container mt-5">
<div class="row justify-content-center">
<div class="col-md-6">
<div class="card shadow
p-4">
<h3 class="mb-3
text-center">Create an Account</h3>
<?php if (isset($success)): ?>
<div class="alert
alert-success"><?= $success ?></div>
<?php elseif (isset($error)): ?>
<div class="alert
alert-danger"><?= $error ?></div>
<?php endif; ?>
<form method="POST">
<div class="mb-3">
<label class="form-label">Full Name</label>
<input class="form-control" name="name" required>
</div>
<div class="mb-3">
<label class="form-label">Email Address</label>
<input class="form-control" name="email" type="email" required>
</div>
<div class="mb-3">
<label class="form-label">Password</label>
<input class="form-control" name="password" type="password" required>
</div>
<button class="btn btn-primary
w-100"
type="submit">Register</button>
<p class="mt-3
text-center">Already have an account? <a href="login.php">Login here</a></p>
</form>
</div>
</div>
</div>
</div>
</body>
</html>
🧩 STEP 5: User Login (auth/login.php)
<?php
session_start();
include '../db/db.php'; // $conn is the mysqli connection
$error = "";
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$email =
mysqli_real_escape_string($conn, $_POST['email']);
$password = $_POST['password'];
$query = "SELECT * FROM users WHERE email='$email'";
$result = mysqli_query($conn,
$query);
if ($result && mysqli_num_rows($result) ==
1) {
$user =
mysqli_fetch_assoc($result);
if
(password_verify($password, $user['password'])) {
$_SESSION['user_id'] = $user['id'];
header("Location:
../dashboard.php");
exit();
} else {
$error
= "❌ Incorrect
password.";
}
} else {
$error = "❌ Email not
found.";
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Login - Modern UI</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="bg-light">
<div class="container mt-5">
<div class="row justify-content-center">
<div class="col-md-6">
<div class="card shadow
rounded-4">
<div class="card-body p-4">
<h2 class="text-center
mb-4">🔐 Login</h2>
<?php if ($error): ?>
<div class="alert alert-danger"><?= $error ?></div>
<?php endif; ?>
<form method="POST" novalidate>
<div class="mb-3">
<label for="email" class="form-label">Email address</label>
<input class="form-control" type="email" name="email" id="email" required placeholder="Enter your
email">
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input class="form-control" type="password" name="password" id="password" required placeholder="Enter your
password">
</div>
<button class="btn btn-success
w-100"
type="submit">Login</button>
</form>
<p class="mt-3
text-center">
Don't
have an account? <a href="register.php">Register here</a>
</p>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
🧩 STEP 6: Dashboard page Email (dashboard.php)
<?php
session_start();
if (!isset($_SESSION['user_id'])) {
header("Location:
auth/login.php");
exit();
}
include 'db/db.php'; // $conn is the mysqli connection
include 'include/header.php';
// Fetch user info
$user_id = $_SESSION['user_id'];
$result = mysqli_query($conn, "SELECT name, email FROM users WHERE id = $user_id");
$user = mysqli_fetch_assoc($result);
?>
<div class="container mt-4">
<div class="row">
<div class="col-md-3"><?php include 'include/sidebar.php'; ?>
</div>
<div class="col-md-9">
<div class="card shadow-sm">
<div class="card-body
text-center">
<h2>Welcome to <span class="text-primary">MyMail</span></h2>
<p class="lead">Hello, <strong><?= htmlspecialchars($user['name']) ?></strong></p>
<p class="text-muted"><?= htmlspecialchars($user['email']) ?></p>
<hr>
</div>
</div>
</div>
<?php include 'include/footer.php'; ?>
🧩 STEP 7: Compose Page (compose.php)
<?php
session_start();
if (!isset($_SESSION['user_id'])) header("Location:
auth/login.php");
include 'db/db.php';
include 'include/header.php';
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$receiver_email = $_POST['to'];
$subject = $_POST['subject'];
$body = $_POST['body'];
$sender_id = $_SESSION['user_id'];
// Escape user inputs for security
$receiver_email =
mysqli_real_escape_string($conn, $receiver_email);
$subject =
mysqli_real_escape_string($conn, $subject);
$body =
mysqli_real_escape_string($conn, $body);
$query = "INSERT INTO messages (sender_id,
receiver_email, subject, body)
VALUES ($sender_id,
'$receiver_email', '$subject', '$body')";
if (mysqli_query($conn, $query)) {
echo "<div
class='alert alert-success m-3'>Message Sent! <a href='inbox.php'>Go
to Inbox</a></div>";
} else {
echo "<div
class='alert alert-danger m-3'>Error: " . mysqli_error($conn) . "</div>";
}
}
?>
<div class="container mt-4">
<div class="row">
<div class="col-md-3"><?php include 'include/sidebar.php'; ?>
</div>
<div class="col-md-9">
<h2>Compose</h2>
<form method="POST">
<input class="form-control my-2" name="to" type="email" required placeholder="To">
<input class="form-control my-2" name="subject" required placeholder="Subject">
<textarea class="form-control my-2" name="body" required placeholder="Write your
message"></textarea>
<button class="btn btn-primary" type="submit">Send</button>
</form>
</div>
</div>
<?php include 'include/footer.php'; ?>
🧩 STEP 8: Inbox Message (inbox.php)
<?php
session_start();
if (!isset($_SESSION['user_id'])) header("Location:
auth/login.php");
include 'db/db.php';
include 'include/header.php';
?>
<div class="container mt-4">
<div class="row">
<div class="col-md-3"><?php include 'include/sidebar.php'; ?>
</div>
<div class="col-md-9">
<div class="content-area">
<?php
$user_id = $_SESSION['user_id'];
$user = $conn->query("SELECT email FROM users WHERE id=$user_id")->fetch_assoc();
$email = $user['email'];
$result = $conn->query("SELECT * FROM messages WHERE receiver_email='$email' ORDER BY sent_at DESC");
?>
<h2>Inbox</h2>
<?php while ($row = $result->fetch_assoc()): ?>
<div class="card mb-3">
<div class="card-body">
<h5 class="card-title"><?= htmlspecialchars($row['subject']) ?></h5>
<p class="card-text">
<strong>From:</strong> <?= htmlspecialchars($row['sender_id']) ?><br>
<small><strong>Received:</strong> <?= htmlspecialchars($row['sent_at']) ?></small>
</p>
<a href="view.php?id=<?= $row['id'] ?>" class="btn
btn-outline-primary btn-sm">View</a>
</div>
</div>
<?php endwhile; ?>
</div>
</div>
<?php include 'include/footer.php'; ?>
🧩 STEP 9: Sent (sent.php)
<?php
session_start();
if (!isset($_SESSION['user_id'])) {
header("Location:
auth/login.php");
exit();
}
include 'db/db.php';
include 'include/header.php';
$user_id = $_SESSION['user_id'];
$query = "SELECT * FROM messages WHERE sender_id = $user_id ORDER BY id DESC";
$result = mysqli_query($conn, $query);
?>
<div class="container mt-4">
<div class="row">
<div class="col-md-3"><?php include 'include/sidebar.php'; ?>
</div>
<div class="col-md-9">
<h2 class="text-primary mb-4">📤 Sent Mail</h2>
<?php if (mysqli_num_rows($result) > 0): ?>
<div class="table-responsive">
<table class="table table-striped
table-bordered shadow-sm rounded">
<thead class="table-dark">
<tr>
<th>#</th>
<th>To</th>
<th>Subject</th>
<th>Message</th>
<th>Date Sent</th>
</tr>
</thead>
<tbody>
<?php
$sn = 1;
while ($row =
mysqli_fetch_assoc($result)):
?>
<tr>
<td><?= $sn++ ?></td>
<td><?= htmlspecialchars($row['receiver_email']) ?></td>
<td><?= htmlspecialchars($row['subject']) ?></td>
<td><?=
nl2br(htmlspecialchars($row['body'])) ?></td>
<td><?= date('d M Y, h:i A', strtotime($row['sent_at'])) ?></td>
</tr>
<?php endwhile; ?>
</tbody>
</table>
</div>
<?php else: ?>
<div class="alert alert-warning">You haven't sent any
messages yet.</div>
<?php endif; ?>
</div>
<?php include 'include/footer.php'; ?>
🧩 STEP 10: view (view.php)
<?php
session_start();
if (!isset($_SESSION['user_id'])) header("Location:
auth/login.php");
include 'db/db.php';
$id = $_GET['id'];
$result = $conn->query("SELECT * FROM messages WHERE id=$id");
$row = $result->fetch_assoc();
?>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
<div class="container mt-4">
<h2><?= htmlspecialchars($row['subject']) ?></h2>
<p><strong>From:</strong> <?= $row['sender_id'] ?></p>
<p><?= nl2br(htmlspecialchars($row['body'])) ?></p>
<small class="text-muted">Sent on: <?= $row['sent_at'] ?></small>
</div>
🧩 STEP 11: Logout (logout.php)
<?php
session_start();
session_destroy();
header("Location: /auth/login.php"); // <-- absolute path
exit();
?>
🧩 STEP 12: Include (header.php)
<?php
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>MyMail - Dashboard</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css" />
<style>
body {
background-color: #f5f7f9ff;
font-family: 'Segoe UI', sans-serif;
}
.topbar {
background-color: #9585f9ff;
padding: 15px 25px;
border-bottom: 2px solid #dee2e6;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
.content {
padding: 30px;
}
.username {
font-weight: bold;
color: #17a2b8;
}
.logout-btn {
background-color: #dc3545;
color: white;
border: none;
padding: 6px 14px;
border-radius: 5px;
text-decoration: none;
}
.logout-btn:hover {
background-color: #c82333;
}
</style>
</head>
<body>
<div class="container-fluid ">
<div class="row">
<!-- Main Content
-->
<div class="topbar d-flex
justify-content-between align-items-center">
<h5 class="mb-0">Dashboard</h5>
<div>
<span class="me-3">Welcome, <span class="username"><?= $_SESSION['user_name'] ?? 'User'; ?></span></span>
<a href="/mymail/auth/logout.php" class="logout-btn" onclick="return confirm('Are you sure you want
to logout?')">Logout</a>
</div>
</div>
🧩 STEP 13: Include (sidebar.php)
<div style="width: 220px; padding: 20px; border-radius:
10px; font-family: 'Segoe UI', sans-serif;">
<h3 style="margin-bottom: 30px; text-align:
center;">📧 MyMail</h3>
<a href="/mymail/dashboard.php" style="display: block;
padding: 10px 15px; margin: 10px 0; background: #ffffff33; border-radius: 8px;
text-decoration: none; transition: background 0.3s;">
🏠 Dashboard
</a>
<a href="/mymail/inbox.php" style="display: block;
padding: 10px 15px; margin: 10px 0; background: #ffffff33; border-radius: 8px;
text-decoration: none; transition: background 0.3s;">
📥 Inbox
</a>
<a href="/mymail/sent.php" style="display: block;
padding: 10px 15px; margin: 10px 0; background: #ffffff33; border-radius: 8px;
text-decoration: none; transition: background 0.3s;">
📤 Sent Mail
</a>
<a href="/mymail/compose.php" style="display: block;
padding: 10px 15px; margin: 10px 0; background: #ffffff33; border-radius: 8px;
text-decoration: none; transition: background 0.3s;">
✉️ Compose
</a>
<a href="/mymail/profile.php" style="display: block;
padding: 10px 15px; margin: 10px 0; background: #ffffff33; border-radius: 8px;
text-decoration: none; transition: background 0.3s;">
👤 Profile
</a>
<a href="/mymail/auth/logout.php" onclick="return confirm('Are you sure you want
to logout?')" style="display: block;
padding: 10px 15px; margin: 10px 0; background: #ff6b6b; border-radius: 8px;
text-decoration: none; transition: background 0.3s;">
🚪 Logout
</a>
</div>
🧩 STEP 14: Include (footer.php)
</div> <!-- Close content
-->
</div> <!-- Close main content
-->
</div> <!-- Close row -->
</div> <!-- Close container -->
<footer class="text-center mt-4 mb-3 text-muted">
<hr>
© <?= date('Y'); ?> MyMail System |
Developed by @lopalopa2007
</footer>
</body>
</html>
🖌️ STEP 15: Style with style.css
Add
styling as needed using CSS for better UI.
✅ Screenshots
index.php
dashboard.php
inbox.php
view.php
sent.php
compse.php
profile.php
4. Version Control & Deployment
- Use of Git and github
- 📝 How to Upload a Project to GitHub
from Your Local System (Step-by-Step Guide)
-
If you're working on a local project (like a PHP project using XAMPP) and want to share it with the world, GitHub is the best place to host your source code. Follow these simple steps to upload your local project to GitHub.
✅ Step 1: Prerequisites
Before you begin, make sure you have:
- ✅ A GitHub account.
- ✅ Git installed on your
computer. Download Git(local Git)
- ✅ A completed or in-progress
project on your local system (e.g., mymail folder in htdocs).
- ✅ A terminal or command prompt
(or Git Bash on Windows).
🚀 Step 2: Create a New Repository on GitHub(Web git---github.com)
1. Login to your GitHub account.
2. Click the ➕ icon in the top-right corner > New Repository.
3. Fill in:
o Repository Name: mymail
o Description (optional): "A simple webmail system using PHP and MySQL."
o Visibility: Choose Public or Private.
4. Click Create repository.
📌 Important: After creating the repo, GitHub will show you some command-line instructions. Keep that page open.
🧱 Step 3: Open Terminal in Your Project Directory
If your project folder is located in C:\xampp\htdocs\mymail, then:
For Git Bash / Command Prompt (Windows):
cd C:/xampp/htdocs/mymail
or
🔗 Step 4: Initialize Git in Your Project
git init
This initializes a new Git repository in your project folder.
📦 Step 5: Add Your Project Files
git add .
This adds all files to your staging area.
✍️ Step 6: Commit Your Changes
git commit -m "Initial commit: Upload MyMail project"
🌐 Step 7: Link Your Local Repo to GitHub Repo
Go back to the GitHub page where you created the repository.
You will find a URL like this:
https://github.com/yourusername/mymail.git
Use this command in terminal:
git remote add origin https://github.com/yourusername/mymail.git
⬆️ Step 8: Push Your Code to GitHub
git push -u origin master
here in local my branch name in my local git is master and in my repository in github having the branch name is main.But both are the same branch then push is possible and ok .So either i have to change the branch name main in github to master or change to local brancha master to main ....i change here global main to master : steps to change main to master branch: ✅ Step-by-Step: Change Default Branch from main to master on GitHub
📌 Step 1: Push Your Local master Branch to GitHub
If your local repo is using the master branch and GitHub has only main, first push your local master:
git push origin master
📌 Step 2: Go to Your GitHub Repository Settings
1. Open your GitHub repository in the browser.
2. Click on the “⚙️ Settings” tab.
3. Scroll down the left sidebar and click on “Branches” under the Code and automation section.
📌 Step 3: Change Default Branch to master
1. In the Default Branch section, click on the “Edit” button.
2. From the dropdown, select master.
3. Click “Update” to confirm.
⚠️ GitHub will show a warning that changing the default branch may affect open PRs and deployments — just accept it.
📌 Step 4: (Optional) Delete the main Branch
If you no longer need the main branch, you can delete it:
git push origin --delete main (from git bash)
Or from GitHub:
- Go to Code → Branches
- Click the Delete icon
next to the main branch.
👉 This command will upload your project to the GitHub repository.
✅ Step 9: Done!
Now visit your GitHub repo URL. You’ll see all your project files uploaded!
✨ Sample GitHub Repository
You can check a demo here:
🔗 https://github.com/lopalopa/mymail - ✅ A GitHub account.
📌 Hosting:
- Here I use InfinityFree.
Live Deployment on Web Hosting (For Public Access)
You’ll need:
- ✅ A domain name (optional)
- ✅ A hosting provider that
supports PHP and MySQL (like Hostinger, GoDaddy, InfinityFree, etc.)
✅ Step 1: Choose a Hosting Provider
Free hosting (for students):
Or paid hosting:
- Hostinger
- GoDaddy
- Bluehost
- https://000webhost.com/
✅ Step 2: Create Hosting Account and Add Domain
1. Sign up and log in to hosting panel (cPanel or custom panel)
2. Set up your domain/subdomain
✅ Step 3: Upload Your PHP Files
- Go to File Manager
- Navigate to public_html/ folder
- Upload your project files there
(either:
- Upload ZIP → extract
- Or upload files manually)
✅ Step 4: Create MySQL Database
1. Open MySQL Database Wizard or MySQL section
2. Create:
o Database name
o Username & password
3. Assign user to database (with All Privileges)
✅ Step 5: Import SQL File
1. Go to phpMyAdmin in cPanel
2. Select your created database
3. Import the SQL file (same as local)
✅ Step 6: Update db.php or config.php
Replace your database config with live hosting credentials:
$host = "localhost"; // or sometimes given as "sqlXXX.hosting.com"
$user = "your_db_username";
$password = "your_db_password";
$database = "your_db_name";
$conn = new mysqli($host, $user, $password, $database);
✅ Step 7: Run Your Website
Go to: my live site
✅ mymail is now live on the internet!- ✅ A domain name (optional)
📌 Summary
This guide gives you the basic structure and flow of how to build an email-like web application in PHP and MySQL.
No comments:
Post a Comment