3 Steps Simple Reservation System with PHP MySQL – Free Download

Welcome to a quick tutorial on how to create a simple reservation system with PHP and MySQL. So you are offering a service and want to open up for online booking? Or maybe you have some rooms available for reservations?

A bare basic reservation system only has a few key components:

  1. A database table to store the reservations.
  2. A PHP library to process the reservations.
  3. The reservation page itself.

But just how is it done exactly? Let us walk an example in this guide – Read on!

ⓘ I have included a zip file with all the source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.

 

QUICK SLIDES

 

TABLE OF CONTENTS

Download & Notes Reservation System Useful Bits & Links
Tutorial Video The End

 

 

DOWNLOAD & NOTES

Firstly, here is the download link to the example code as promised.

 

EXAMPLE CODE DOWNLOAD

Click here to download the source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.

 

QUICK NOTES

  • Create a database and import the 1-reserve.sql file.
  • Change the database settings in 2-reserve.php to your own.
  • Launch 3-reservation.php in the browser, and that’s it.

If you spot a bug, please feel free to comment below. I try to answer questions too, but it is one person versus the entire world… If you need answers urgently, please check out my list of websites to get help with programming.

 

RESERVATION SYSTEM

All right, let us now get started with the reservation system.

 

STEP 1) RESERVATIONS DATABASE TABLE

1-reserve.sql
CREATE TABLE `reservations` (
  `res_id` int(11) NOT NULL,
  `res_date` date,
  `res_slot` varchar(32) DEFAULT NULL,
  `res_name` varchar(255) NOT NULL,
  `res_email` varchar(255) NOT NULL,
  `res_tel` varchar(60) NOT NULL,
  `res_notes` text DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

ALTER TABLE `reservations`
  ADD PRIMARY KEY (`res_id`),
  ADD KEY `res_date` (`res_date`),
  ADD KEY `res_slot` (`res_slot`),
  ADD KEY `res_name` (`res_name`),
  ADD KEY `res_email` (`res_email`),
  ADD KEY `res_tel` (`res_tel`);

ALTER TABLE `reservations`
  MODIFY `res_id` int(11) NOT NULL AUTO_INCREMENT;
Field Description
res_id Reservation ID. Primary key, auto-increment.
res_date Self-explanatory, the reservation date.
res_slot For time slot booking, this is an open text field that is up to you to decide – Offer hourly slots, AM/PM, or don’t use this at all (for whole day booking).
res_name Name of the customer.
res_email Email of the customer.
res_tel Telephone number of the customer.
res_notes Reservation notes, if any.

That should cover all the basics, feel free to add more fields as your project requires.

 

 

STEP 2) PHP RESERVATION CLASS

2-reserve.php
<?php
class Reservation {
  // (A) PROPERTIES
  private $pdo; // PDO object
  private $stmt; // SQL statement
  public $error; // Error message

  // (B) CONSTRUCTOR - CONNECT TO DATABASE
  function __construct() {
    try {
      $this->pdo = new PDO(
        "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=" . DB_CHARSET,
        DB_USER, DB_PASSWORD, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
      );
    } catch (Exception $ex) { die($ex->getMessage()); }
  }

  // (C) DESTRUCTOR - CLOSE DATABASE CONNECTION
  function __destruct() {
    $this->pdo = null;
    $this->stmt = null;
  }

  // (D) SAVE RESERVATION
  function save ($date, $slot, $name, $email, $tel, $notes="") {
    // (D1) CHECKS & RESTRICTIONS
    // @TODO - ADD YOUR OWN RULES & REGULATIONS HERE
    // MAX # OF RESERVATIONS ALLOWED?
    // USER CAN ONLY BOOK X DAYS IN ADVANCE?
    // USER CAN ONLY BOOK A MAX OF X SLOTS WITHIN Y DAYS?

    // (D2) DATABASE ENTRY
    try {
      $this->stmt = $this->pdo->prepare(
        "INSERT INTO `reservations` (`res_date`, `res_slot`, `res_name`, `res_email`, `res_tel`, `res_notes`) VALUES (?,?,?,?,?,?)"
      );
      $this->stmt->execute([$date, $slot, $name, $email, $tel, $notes]);
    } catch (Exception $ex) {
      $this->error = $ex->getMessage();
      return false;
    }

    // (D3) EMAIL
    // @TODO - REMOVE IF YOU WANT TO MANUALLY CALL TO CONFIRM OR SOMETHING
    // OR EMAIL THIS TO A MANAGER OR SOMETHING
    $subject = "Reservation Received";
    $message = "Thank you, we have received your request and will process it shortly.";
    @mail($email, $subject, $message);
    return true;
  }
  
  // (E) GET RESERVATIONS FOR THE DAY
  function getDay ($day="") {
    // (E1) DEFAULT TO TODAY
    if ($day=="") { $day = date("Y-m-d"); }
    
    // (E2) GET ENTRIES
    $this->stmt = $this->pdo->prepare(
      "SELECT * FROM `reservations` WHERE `res_date`=?"
    );
    $this->stmt->execute([$day]);
    return $this->stmt->fetchAll(PDO::FETCH_NAMED);
  }
}

// (F) DATABASE SETTINGS - CHANGE THESE TO YOUR OWN!
define('DB_HOST', 'localhost');
define('DB_NAME', 'test');
define('DB_CHARSET', 'utf8');
define('DB_USER', 'root');
define('DB_PASSWORD', '');

// (G) NEW RESERVATION OBJECT
$_RSV = new Reservation();

Yes, this library looks massive at first, but keep calm and look carefully.

  • When a $_RSV = new Reservation() object is created, the constructor will automatically connect to the database; The destructor will close the connection when done.
  • There are only 2 functions here!
    • function save() This will be used to save the reservation when the user submits the reservation/booking form.
    • function get() Gets all reservations for a specified day, an example of what you might want to use in your own admin panel.

That should cover all the raw essentials of a reservations system.

 

 

STEP 3) DUMMY RESERVATIONS PAGE

THE HTML

3-reservation.php
<?php
// (A) PROCESS RESERVATION
if (isset($_POST['date'])) {
  require "2-reserve.php";
  if ($_RSV->save(
    $_POST['date'], $_POST['slot'], $_POST['name'],
    $_POST['email'], $_POST['tel'], $_POST['notes'])) {
     echo "<div class='ok'>Reservation saved.</div>";
  } else { echo "<div class='err'>".$_RSV->error."</div>"; }
}
?>

<!-- (B) RESERVATION FORM -->
<h1>RESERVATION</h1>
<form id="resForm" method="post" target="_self">
  <label for="res_name">Name</label>
  <input type="text" required name="name" value="John Doe"/>

  <label for="res_email">Email</label>
  <input type="email" required name="email" value="john@doe.com"/>

  <label for="res_tel">Telephone Number</label>
  <input type="text" required name="tel" value="123456789"/>

  <label for="res_notes">Notes (if any)</label>
  <input type="text" name="notes" value="Testing"/>

  <?php
  // @TODO - MINIMUM DATE (TODAY)
  // $mindate = date("Y-m-d", strtotime("+2 days"));
  $mindate = date("Y-m-d");
  ?>
  <label>Reservation Date</label>
  <input type="date" required id="res_date" name="date" value="<?=date("Y-m-d")?>">

  <label>Reservation Slot</label>
  <select name="slot">
    <option value="AM">AM</option>
    <option value="PM">PM</option>
  </select>

  <input type="submit" value="Submit"/>
</form>

No need to panic – This looks confusing, but is actually very straightforward.

  • B – This should be self-explanatory, the HTML reservation form itself.
  • A – When the form is submitted, we use the library to process save the reservation.

 

 

THE CSS

3-theme.css
#resForm {
  max-width: 400px;
  padding: 15px;
  background: #f2f2f2;
  border: 1px solid #aaa;
}
#resForm label, #resForm input, #resForm select {
  display: block;
  box-sizing: border-box;
  width: 100%;
  padding: 5px;
  margin: 5px 0;
}
#resForm input[type="submit"] {
  background: #5c76d4;
  color: #fff;
  border: 0;
  padding: 15px 0;
  margin-top: 15px;
  cursor: pointer;
}
div.ok, div.err { 
  padding: 5px; 
  font-weight: bold;
}
div.ok { 
  background: #9cffbb; 
  border: 1px solid #1ca526;
}
div.err { 
  background: #ffe0e0; 
  border: 1px solid #bb1919;
}
html, body { font-family: arial, sans-serif; }

Just some CSS cosmetics, feel free to adopt in your own project… Or choose to totally ignore it.

 

 

EXTRA) RESERVATIONS REPORT

Everyone is going to have a different system and starting point, but here is another small script that will demonstrate how the library can be used to generate reports.

4-report.php
// (A) GET ALL RESERVATIONS
require "2-reserve.php";
$all = $_RSV->getDay();

// (B) OUTPUT CSV
header('Content-Type: text/csv');
header('Content-Disposition: attachment;filename=reservations.csv');
if (count($all)==0) { echo "No reservations"; }
else {
  // (B1) FIRST ROW - HEADERS
  foreach ($all[0] as $k=>$v) { echo "$k,"; }
  echo "\r\n";
  
  // (B2) RESERVATION DETAILS
  foreach ($all as $r) { 
    foreach ($r as $k=>$v) { echo "$v,"; }
    echo "\r\n";
  }
}

 

 

USEFUL BITS & LINKS

That’s all for the project, and here are a few small extras that may be useful to you.

 

ADDING MORE FIELDS

  • Change the database table, add more fields.
  • Update function save() to also include the extra fields.
  • Lastly, update the HTML form.

 

I DON’T NEED THE TIME SLOT

Just leave it as NULL, or remove it totally.

 

DATE RANGE BOOKING

This is kind of tricky, as everyone will have different requirements. For example:

  • Some may have AM/PM timeslots. Booking an overnight stay may mean “Day 1 PM plus DAY 2 AM”, and not “2 full days”. So yep, that is 2 timeslots.
  • Others may only offer “full-day bookings”. In this case, feel free to change the database to “date start and date end” instead of “date and time slot”.
  • A few others may get extremely complicated with “pay by the hour”. In this case, it is best to store “time start” and “time end” instead.

There is no way to create a “one-size-fits-all” system here – This is your homework.

 

LINKS & REFERENCES

 

TUTORIAL VIDEO

 

INFOGRAPHIC CHEATSHEET

PHP MYSQL Reservation (Click To Enlarge)

 

THE END

Thank you for reading, and we have come to the end of this guide. I hope that it has helped you with your project, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!

27 thoughts on “3 Steps Simple Reservation System with PHP MySQL – Free Download”

  1. Hi W.S. Toh
    Is there a way to implement this code so logged in user details will be passed to DB instead of manually inputting name, email, etc? Even the userId from login will be enough to make it work.

    Thanks a lot

    1. Just start the session and pass the user into the booking functions?

      session_start(); 
      $_RSV->save(
        DATE, SLOT,
        $_SESSION['user']['name'], $_SESSION['user']['email'], 
        ...
      );
    1. No, but you can add one very easily in 2-reserve.php –

      function delBooking ($id) {
        try {
          $this->stmt = $this->pdo->prepare("DELETE FROM `reservations` WHERE `res_id`=?");
          $this->stmt->execute([$id]);
          return true;
        } catch (Exception $ex) {
          $this->error = $ex->getMessage();
          return false;
        }
      }
  2. Thank you so much, it worked as expected, is there a way for me to add more people on the same day , time will be used as validation for reserving a spot on the same day at a particular time.

    1. The laziest way is to just add more res_name_A, res_name_B, ... fields in the reservations table. Modify the HTML form to add more name fields, and the SQL to also insert the extra names.

      But for good design, I will recommend creating a separate reservations_people table.

    1. What a coincidence! I was expecting people who say “was expecting a demo page” to sponsor a couple of million dollars first too. 🙄 Maybe then, it will be enough to get a better server, firewall, managed hosting, run a team to finally develop and put up the demo for hundreds of examples and tutorials all over this blog…

      But since that is not commercially viable and possible, maybe a little less self-entitlement will help along with the already free script download > https://code-boxx.com/faq/#nodemo 😆

Leave a Comment

Your email address will not be published. Required fields are marked *