How to develop Projects Using PHP and Mysql
Part 10
1️⃣ Event Management System
Module 2: Book the Event
Purpose:
Allows users to browse and book events as well as view detailed
information about each event.
Functionalities:
✅ View the list of upcoming events with
title, date, time, venue, and description.
✅ View detailed
information about a single event.
✅ Book an event by
providing user details (e.g., name, email, number of seats).
✅ Cancel a booked event
(if allowed).
Project Structure:
/events/
│
├── event_list.php # List all available events
├── view_event.php # Display detailed info for a single
event
├── book_event.php # Book a selected event
├── cancel_booking.php # Cancel a booking (if permitted)
├── my_bookings.php # View events booked by the user
Database Tables:
1. events
CREATE TABLE events (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
description TEXT,
event_date DATETIME NOT NULL,
location VARCHAR(255) NOT NULL,
organizer_id INT,
image VARCHAR(255),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (organizer_id) REFERENCES
users(id) ON DELETE SET NULL
);
2. bookings
CREATE TABLE bookings (
id INT AUTO_INCREMENT PRIMARY KEY,
event_id INT NOT NULL,
user_id INT NOT NULL,
seats INT DEFAULT 1,
booking_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
status ENUM('Booked', 'Cancelled') DEFAULT 'Booked',
FOREIGN KEY (event_id) REFERENCES
events(id) ON DELETE CASCADE,
FOREIGN KEY (user_id) REFERENCES users(id) ON
DELETE CASCADE
);
✅ event_list.php
<?php
// Start session
session_start();
// Include database
connection
include '../config/db_connect.php';
// Fetch all upcoming
events
$sql = "SELECT *
FROM events WHERE event_date >= NOW() ORDER BY event_date ASC";
$result = mysqli_query($conn,
$sql);
?>
<!DOCTYPE html>
<html>
<head>
<title>Event List</title>
<link rel="stylesheet" href="../assets/style.css">
<!-- Optional CSS -->
<style>
body { font-family: Arial, sans-serif;
background-color: #f7f7f7; padding: 20px; }
.event-card {
background-color: #fff;
padding: 15px;
margin-bottom: 20px;
border-radius: 10px;
box-shadow: 0px 0px 5px rgba(0,0,0,0.1);
}
.event-card h2 { margin-top: 0; }
.event-card .date { color: #666;
font-size: 0.9em; }
.event-card .btn {
display: inline-block;
padding: 8px 15px;
background-color: #007BFF;
color: white;
text-decoration: none;
border-radius: 5px;
margin-top: 10px;
}
.event-card .btn:hover {
background-color: #0056b3;
}
</style>
</head>
<body>
<h1>Upcoming Events</h1>
<?php if (mysqli_num_rows($result) > 0):
?>
<?php while($row = mysqli_fetch_assoc($result)):
?>
<div class="event-card">
<h2><?php echo htmlspecialchars($row['title']);
?></h2>
<p class="date"><strong>Date:</strong>
<?php echo date("F j, Y, g:i a", strtotime($row['event_date']));
?></p>
<p><strong>Venue:</strong>
<?php echo htmlspecialchars($row['location']); ?></p>
<p><?php echo nl2br(htmlspecialchars(substr($row['description'],
0, 150))) . '...'; ?></p>
<a class="btn" href="view_event.php?id=<?php
echo $row['id']; ?>">View & Book</a>
</div>
<?php endwhile; ?>
<?php else: ?>
<p>No upcoming events found.</p>
<?php endif; ?>
</body>
</html>
✅ Notes:
- This
code connects to your database using db_connect.php.
- It
fetches events from the events table where the event date is in the
future.
- Each
event has:
- Title
- Date
& Time
- Venue
- Description
(trimmed)
- A
link to view full details and book (view_event.php?id=...)
✅ view_event.php
<?php
// Start session
session_start();
// Include DB connection
include '../config/db_connect.php';
// Get the event ID from
the URL
if (isset($_GET['id'])
&& is_numeric($_GET['id'])) {
$event_id = $_GET['id'];
// Fetch event details
$sql = "SELECT * FROM events WHERE id
= $event_id";
$result = mysqli_query($conn, $sql);
if ($result && mysqli_num_rows($result)
=== 1) {
$event = mysqli_fetch_assoc($result);
} else {
echo "Event not found.";
exit;
}
} else {
echo "Invalid event ID.";
exit;
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Event Details</title>
<link rel="stylesheet" href="../assets/style.css">
<!-- Optional -->
<style>
body { font-family: Arial, sans-serif;
background-color: #f9f9f9; padding: 30px; }
.event-container {
background-color: #fff;
padding: 25px;
border-radius: 10px;
box-shadow: 0px 0px 8px rgba(0,0,0,0.1);
max-width: 700px;
margin: auto;
}
h2 { margin-top: 0; }
.info { margin: 10px 0; }
.btn {
padding: 10px 20px;
background-color: #28a745;
color: white;
text-decoration: none;
border-radius: 6px;
display: inline-block;
margin-top: 20px;
}
.btn:hover {
background-color: #218838;
}
</style>
</head>
<body>
<div class="event-container">
<h2><?php echo htmlspecialchars($event['title']);
?></h2>
<p class="info"><strong>Date
& Time:</strong>
<?php echo date("F j, Y, g:i a",
strtotime($event['event_date'])); ?>
</p>
<p class="info"><strong>Venue:</strong>
<?php echo htmlspecialchars($event['location']); ?></p>
<?php if (!empty($event['image'])):
?>
<p><img src="../uploads/<?php
echo $event['image']; ?>" width="100%" style="max-height:300px;
object-fit:cover; border-radius:10px;"></p>
<?php endif; ?>
<p class="info"><?php echo
nl2br(htmlspecialchars($event['description'])); ?></p>
<!-- Book Now Button -->
<a class="btn" href="book_event.php?id=<?php
echo $event['id']; ?>">Book Now</a>
</div>
</body>
</html>
🔧 Assumptions:
- Your
database connection file is named db_connect.php.
- You’re
storing event images in a ../uploads/ folder.
- The
event ID is passed via GET (view_event.php?id=1).
- You’ll
handle the actual booking in book_event.php.
✅ book_event.php
<?php
// Start session
session_start();
// Include database
connection
include '../config/db_connect.php';
// Initialize variables
$event_id = isset($_GET['id'])
? intval($_GET['id']) : 0;
$name = $email = $seats =
"";
$errors = [];
// Fetch event details
$event_query = "SELECT
* FROM events WHERE id = $event_id";
$event_result = mysqli_query($conn,
$event_query);
if (!$event_result || mysqli_num_rows($event_result)
!== 1) {
echo "Event not found.";
exit;
}
$event = mysqli_fetch_assoc($event_result);
// Handle form submission
if ($_SERVER['REQUEST_METHOD']
=== 'POST') {
// Collect and validate form data
$name = trim($_POST['name']);
$email = trim($_POST['email']);
$seats = intval($_POST['seats']);
if (empty($name)) {
$errors[] = "Name is
required.";
}
if (!filter_var($email,
FILTER_VALIDATE_EMAIL)) {
$errors[] = "Valid email is
required.";
}
if ($seats < 1) {
$errors[] = "Please book at least
1 seat.";
}
// If no errors, insert booking
if (empty($errors)) {
$stmt = $conn->prepare("INSERT
INTO bookings (event_id, user_id, seats, booking_date) VALUES (?, NULL, ?,
NOW())");
$stmt->bind_param("ii", $event_id,
$seats);
if ($stmt->execute()) {
$success = "Booking
successful!";
} else {
$errors[] = "Failed to book.
Please try again.";
}
}
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Book Event - <?php echo htmlspecialchars($event['title']);
?></title>
<style>
body { font-family: Arial;
background-color: #f2f2f2; padding: 20px; }
.form-container {
max-width: 600px;
background: white;
padding: 25px;
margin: auto;
border-radius: 10px;
box-shadow: 0px 0px 8px rgba(0,0,0,0.1);
}
input, label {
display: block;
width: 100%;
margin-bottom: 15px;
}
input[type="text"],
input[type="email"], input[type="number"] {
padding: 10px;
border: 1px solid #ccc;
border-radius: 6px;
}
.btn {
background-color: #28a745;
color: white;
padding: 10px 15px;
text-decoration: none;
border: none;
border-radius: 6px;
cursor: pointer;
}
.btn:hover {
background-color: #218838;
}
.error { color: red; margin-bottom: 10px;
}
.success { color: green; margin-bottom:
10px; }
</style>
</head>
<body>
<div class="form-container">
<h2>Book Event: <?php echo htmlspecialchars($event['title']);
?></h2>
<?php if (!empty($errors)): ?>
<div class="error">
<?php foreach ($errors as $e) echo
"<p>$e</p>"; ?>
</div>
<?php endif; ?>
<?php if (!empty($success)): ?>
<div class="success"><?php
echo $success; ?></div>
<?php else: ?>
<form method="POST" action="">
<label for="name">Your
Name:</label>
<input type="text" name="name"
value="<?php echo htmlspecialchars($name); ?>" required>
<label for="email">Your
Email:</label>
<input type="email" name="email"
value="<?php echo htmlspecialchars($email); ?>" required>
<label for="seats">Number
of Seats:</label>
<input type="number" name="seats"
min="1" value="<?php echo htmlspecialchars($seats);
?>" required>
<button type="submit" class="btn">Book
Now</button>
</form>
<?php endif; ?>
</div>
</body>
</html>
🔧 Database Reminder:
Make sure your bookings
table exists and looks something like this:
CREATE TABLE bookings (
id INT AUTO_INCREMENT PRIMARY KEY,
event_id INT NOT NULL,
user_id INT, -- Optional if not using login
seats INT DEFAULT 1,
booking_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
status ENUM('Booked', 'Cancelled') DEFAULT 'Booked',
FOREIGN KEY (event_id) REFERENCES
events(id) ON DELETE CASCADE
);
✅ cancel_booking.php
<?php
// Start session
session_start();
// Include DB connection
include '../config/db_connect.php';
// Get booking ID from
URL
if (!isset($_GET['id'])
|| !is_numeric($_GET['id'])) {
echo "Invalid booking ID.";
exit;
}
$booking_id = intval($_GET['id']);
$message = "";
// Step 1: Check if
booking exists and is not already cancelled
$query = "SELECT *
FROM bookings WHERE id = $booking_id AND status = 'Booked'";
$result = mysqli_query($conn,
$query);
if (!$result || mysqli_num_rows($result)
!== 1) {
$message = "Booking not found or
already cancelled.";
} else {
// Step 2: Cancel the booking
$cancel_sql = "UPDATE bookings SET
status = 'Cancelled' WHERE id = $booking_id";
if (mysqli_query($conn, $cancel_sql)) {
$message = "Booking has been
successfully cancelled.";
} else {
$message = "Error cancelling
booking.";
}
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Cancel Booking</title>
<style>
body { font-family: Arial; background: #f9f9f9;
padding: 40px; text-align: center; }
.message-box {
background-color: #fff;
max-width: 500px;
margin: auto;
padding: 30px;
border-radius: 10px;
box-shadow: 0px 0px 10px rgba(0,0,0,0.1);
}
.success { color: green; }
.error { color: red; }
a.btn {
display: inline-block;
margin-top: 20px;
padding: 10px 20px;
background: #007bff;
color: white;
text-decoration: none;
border-radius: 6px;
}
a.btn:hover {
background-color: #0056b3;
}
</style>
</head>
<body>
<div class="message-box">
<h2>Cancel Booking</h2>
<p class="<?php echo (strpos($message,
'successfully') !== false) ? 'success' : 'error'; ?>">
<?php echo $message; ?>
</p>
<a href="my_bookings.php" class="btn">Back
to My Bookings</a>
</div>
</body>
</html>
🔍 Key Features:
- Checks
if the booking exists and is currently "Booked".
- Updates
the status to "Cancelled".
- Displays
a friendly message and a button to return to my_bookings.php.
✅ Make sure your bookings table
supports this:
ALTER TABLE bookings ADD COLUMN
status ENUM('Booked', 'Cancelled') DEFAULT 'Booked';
✅ my_bookings.php
<?php
// Start session
session_start();
// Include database
connection
include '../config/db_connect.php';
// For demo: Assume user
ID = 1 (replace with actual user session ID in real implementation)
$user_id = 1;
// Fetch bookings for
this user
$sql = "SELECT b.id
AS booking_id, b.seats, b.status, b.booking_date,
e.title, e.event_date,
e.location
FROM bookings b
JOIN events e ON b.event_id = e.id
WHERE b.user_id = $user_id
ORDER BY b.booking_date DESC";
$result = mysqli_query($conn,
$sql);
?>
<!DOCTYPE html>
<html>
<head>
<title>My Bookings</title>
<style>
body { font-family: Arial; background: #f2f2f2;
padding: 20px; }
.container {
max-width: 900px;
margin: auto;
background: white;
padding: 30px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 15px;
}
th, td {
border: 1px solid #ccc;
padding: 12px;
text-align: center;
}
th {
background: #007bff;
color: white;
}
.btn-cancel {
background: #dc3545;
color: white;
padding: 5px 10px;
border: none;
border-radius: 5px;
text-decoration: none;
}
.btn-cancel:hover {
background: #c82333;
}
.status-booked {
color: green;
font-weight: bold;
}
.status-cancelled {
color: red;
font-weight: bold;
}
</style>
</head>
<body>
<div class="container">
<h2>My Event Bookings</h2>
<?php if (mysqli_num_rows($result) >
0): ?>
<table>
<thead>
<tr>
<th>#</th>
<th>Event Title</th>
<th>Event Date</th>
<th>Location</th>
<th>Seats</th>
<th>Status</th>
<th>Booked On</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php $count = 1; while ($row
= mysqli_fetch_assoc($result)): ?>
<tr>
<td><?php echo
$count++; ?></td>
<td><?php echo
htmlspecialchars($row['title']); ?></td>
<td><?php echo
date('d M Y, h:i A', strtotime($row['event_date'])); ?></td>
<td><?php echo
htmlspecialchars($row['location']); ?></td>
<td><?php echo
$row['seats']; ?></td>
<td class="<?php
echo ($row['status'] === 'Booked') ? 'status-booked' : 'status-cancelled';
?>">
<?php echo $row['status'];
?>
</td>
<td><?php echo
date('d M Y', strtotime($row['booking_date'])); ?></td>
<td>
<?php if ($row['status']
=== 'Booked'): ?>
<a href="cancel_booking.php?id=<?php
echo $row['booking_id']; ?>" class="btn-cancel"
onclick="return
confirm('Are you sure you want to cancel this booking?');">
Cancel
</a>
<?php else:
?>
N/A
<?php endif;
?>
</td>
</tr>
<?php endwhile; ?>
</tbody>
</table>
<?php else: ?>
<p>You have not booked any events
yet.</p>
<?php endif; ?>
</div>
</body>
</html>
🔧 Notes:
- Assumes
you’re tracking the logged-in user with user_id. Replace the $user_id = 1;
line with session-based logic like:
$user_id = $_SESSION['user_id'];
- Shows
each booking's:
- Title
- Date
and location
- Seats
booked
- Status
(Booked / Cancelled)
- Option
to cancel (only if currently booked)