4 Steps GPS Tracking System With PHP and Javascript

Welcome to a tutorial on how to create a GPS tracking system with PHP and Javascript. Need to track where a vehicle is at? Where an order is, or just making sure that it has been delivered to the right place?

A basic GPS tracking system with PHP and Javascript requires the following components:

  1. A database table to record the last known locations.
  2. PHP library and endpoint to accept and manage the location updates.
  3. A webpage or application to send the rider’s current GPS location to the server.
  4. Lastly, an admin page to track all the riders.

Let us walk through a simple 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.

 

 

TABLE OF CONTENTS

Download & Notes The Database PHP Core
Tracker Admin Useful Bits & Links
The End

 

DOWNLOAD & NOTES

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

 

SOURCE 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.

 

QUICKSTART

  1. Create a database and import the 1-database.sql file.
  2. Change the database settings in 2a-core.php to your own.
  3. 3-track.html is the client/rider tracking page, 4-admin.html is the demo admin page. Captain Obvious – Use http:// not file://

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.

 

 

STEP 1) THE DATABASE

All right, let us now start by laying the foundation – The database. No worries, just a simple table here.

 

LAST KNOWN LOCATION

database.sql
CREATE TABLE `gps_track` (
  `rider_id` int(11) NOT NULL,
  `track_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `track_lng` decimal(11,7) NOT NULL,
  `track_lat` decimal(11,7) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

ALTER TABLE `gps_track`
  ADD PRIMARY KEY (`rider_id`),
  ADD KEY `track_time` (`track_time`);
Field Description
rider_id Primary key, the rider ID… Or the ID of whatever you want to track.
track_time Time the rider last “checked in”.
track_lng Longitude.
track_lat Latitude.

Yep, that is all we need. Just a table to store the last-known locations of the riders.

 

 

STEP 2) PHP CORE LIBRARY & ENDPOINT

Next, we will establish another piece of the foundations – The endpoint of the GPS tracking system which will receive and serve the GPS coordinates.

 

GPS TRACKING PHP CORE LIBRARY

2a-core.php
<?php
class Track {
  // (A) CONSTRUCTOR - CONNECT TO DATABASE
  public $pdo = null;
  public $stmt = null;
  public $error = "";
  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,
          PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
        ]
      );
    } catch (Exception $ex) { exit($ex->getMessage()); }
  }

   // (B) DESTRUCTOR - CLOSE CONNECTION
  function __destruct () {
    if ($this->stmt !== null) { $this->stmt = null; }
    if ($this->pdo !== null) { $this->pdo = null; }
  }

  // (C) HELPER FUNCTION - EXECUTE SQL QUERY
  function query ($sql, $data=null) {
    try {
      $this->stmt = $this->pdo->prepare($sql);
      $this->stmt->execute($data);
      return true;
    } catch (Exception $ex) {
      $this->error = $ex->getMessage();
      return false;
    }
  }
 
  // (D) UPDATE RIDER COORDINATES
  function update ($id, $lng, $lat) {
    return $this->query(
      "REPLACE INTO `gps_track` (`rider_id`, `track_time`, `track_lng`, `track_lat`) VALUES (?, ?, ?, ?)",
      [$id, date("Y-m-d H:i:s"), $lng, $lat]
    );
  }
 
  // (E) GET RIDER COORDINATES
  function get ($id) {
    $this->query("SELECT * FROM `gps_track` WHERE `rider_id`=?", [$id]);
    return $this->stmt->fetch();
  }

  // (F) GET ALL THE RIDER LOCATIONS
  function getAll () {
    $this->query("SELECT * FROM `gps_track`");
    return $this->stmt->fetchAll();
  }
}
 
// (G) 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', '');
 
// (H) START!
$_TRACK = new Track();

This one looks intimidating at first, but keep calm and analyze slowly.

  • A & B – When the $_TRACK = new Track() object is created, the constructor will automatically connect to the database. The destructor closes the connection.
  • C – query() is a simple helper function that runs an SQL query.
  • D – update() records a rider’s GPS coordinates.
  • E – get() returns a rider’s last known coordinates.
  • F – getAll() returns all riders’ last known coordinates.

 

 

AJAX ENDPOINT

2b-ajax-track.php
<?php
// (A) INIT
require "2a-core.php";
switch ($_POST['req']) {
  // (B) INVALID REQUEST
  default:
    echo "Invalid request.";
    break;

  // (C) UPDATE RIDER LOCATION
  case "update":
    $pass = $_TRACK->update($_POST['rider_id'], $_POST['lng'], $_POST['lat']);
    echo json_encode([
      "status" => $pass ? 1 : 0,
      "message" => $pass ? "OK" : $trackLib->error
    ]);
    break;

  // (D) GET RIDER LOCATION
  case "get":
    $location = $_TRACK->get($_POST['rider_id']);
    echo json_encode([
      "status" => is_array($location) ? 1 : 0,
      "message" => $location
    ]);
    break;

  // (E) GET ALL RIDER LOCATIONS
  case "getAll":
    $location = $_TRACK->getAll();
    echo json_encode([
      "status" => is_array($location) ? 1 : 0,
      "message" => $location
    ]);
    break;
}

The core library is not going to work itself, so here is the AJAX endpoint. How it works is very simple – Just pass in a $_POST['req'] to specify the request, followed by the required parameters.

Request Description
update Update the location of the given rider. Parameters:

  • rider_id
  • lng
  • lat
get Get the last known location of a given rider. Parameters:

  • rider_id
getAll Get all the last-known locations of the riders.

 

 

STEP 3) TRACKER

Now that the server-side foundations ready, we have to build a simple client-side tracker that will update the server of the rider’s current locations.

 

JAVASCRIPT GPS TRACKER

3-track.html
<script>
var track = {
  // (A) PROPERTIES & SETTINGS
  rider : 999, // Rider ID - Fixed to 999 for this demo.
  delay : 10000, // Delay between GPS update, in milliseconds.
  timer : null, // Interval timer.
  display : null, // HTML <p> element.
 
  // (B) INIT
  init : function () {
    track.display = document.getElementById("display");
    if (navigator.geolocation) {
      track.update();
      setInterval(track.update, track.delay);
    } else {
      track.display.innerHTML = "Geolocation is not supported!";
    }
  },
 
  // (C) UPDATE CURRENT LOCATION TO SERVER
  update : function () {
    navigator.geolocation.getCurrentPosition(function (pos) {
      // (C1) LOCATION DATA
      var data = new FormData();
      data.append('req', 'update');
      data.append('rider_id', track.rider);
      data.append('lat', pos.coords.latitude);
      data.append('lng', pos.coords.longitude);
 
      // (C2) AJAX
      var xhr = new XMLHttpRequest();
      xhr.open('POST', "2b-ajax-track.php");
      xhr.onload = function () {
      var res = JSON.parse(this.response);
        if (res.status==1) {
          track.display.innerHTML = Date.now() + " | Lat: " + pos.coords.latitude + " | Lng: " + pos.coords.longitude;
        } else {
          track.display.innerHTML = res.message;
        }
      };
      xhr.send(data);
    });
  }
};
window.addEventListener("DOMContentLoaded", track.init);
</script>
 
<p id="display"></p>

Yep, this seems massive at first. But it is basically using navigator.geolocation.getCurrentPosition() to get the current GPS location, and uploading it to the server via AJAX. That is the gist of it, and of course, there is always the option to create an Android/iOS app to do this as well.

 

 

STEP 4) ADMIN PANEL

The final piece of the puzzle is to have an admin page that will extract the locations of the riders and show them on a map.

 

THE CENTRAL CONTROL

4-admin.html
<script>
var track = {
  // (A) PROPERTIES
  map : null, // HTML map
  delay : 10000, // Delay between location refresh
 
  // (B) INIT
  init : function () {
    track.map = document.getElementById("map");
    track.show();
    setInterval(track.show, track.delay);
  },
 
  // (C) GET DATA FROM SERVER AND UPDATE MAP
  show : function () {
    // (C1) DATA
    var data = new FormData();
    data.append('req', 'getAll');
 
    // (C2) AJAX
    var xhr = new XMLHttpRequest();
    xhr.open('POST', "2b-ajax-track.php");
    xhr.onload = function () {
      track.map.innerHTML = "<div>LOADED "+Date.now()+"</div>";
      var res = JSON.parse(this.response);
      if (res.status==1) {
        for (let rider of res.message) {
          var dummy = document.createElement("div");
          dummy.innerHTML = "Rider ID " + rider.rider_id + " | Lng " + rider.track_lng + " | Lat " + rider.track_lat + " | Updated " + rider.track_time;
          track.map.appendChild(dummy);
        }
      } else { track.map.innerHTML = res.message; }
    };
    xhr.send(data);
  }
};
window.addEventListener("DOMContentLoaded", track.init);
</script>
 
<div id="map"></div>

This is just a dummy admin page that shows all the locations of the riders.

 

USEFUL BITS & LINKS

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

 

WHERE ARE THE MAPS?

Yes, there are no maps in this example. Because there are dozens of map services in the world, I don’t want to advocate nor restrict anyone to using one. If you need an example of how to create a map, check out the links below.

 

LIMITATIONS & REAL-TIME TRACKING?

Hey, this is not a real-time system! Of course, it is not. While it is possible to do so, we have to consider the technical limitations and is it worth doing.

  • Firstly, real-time will drain out the smartphone batteries fast.
  • Secondly, you will need a powerful network infrastructure to support a lot of “always-on” socket connections.
  • Lastly, a very robust server system that is capable of crunching real-time data.

So aye… If someone is willing to shell out that kind of money and think that it is beneficial for their business – Then why not?

 

FUTURE DEVELOPMENT

Captain Obvious to the rescue, this tutorial totally disregarded the login mechanism and security – Remember to implement your own rider/customer/admin login. Restrict the information that each can access.

 

LINKS & REFERENCES

Here’s a tutorial that I did on MapBox if you are interested.

How To Get GPS Coordinates & Generate Map In Javascript

 

YOUTUBE TUTORIAL

 

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!

15 thoughts on “4 Steps GPS Tracking System With PHP and Javascript”

    1. Not too sure if leaving an email to invite spam is a good idea… But I will respect that.

      Anyway, go through the entire tutorial and what you are looking for is already there.

  1. Thank you very much you’ve been so helpful
    i have to do a symfony project about geo-tracking application which include dealing with alerts like geofencing, eco-driving and fuel saving.
    if you make a tutorial about these issues that would be very kind of you and thank you again sharing the knowledge is better than sharing monney.

    1. Edit – OpenStreetMap does not provide “direct end-user service”. Look for other map providers such as Mapbox and Thnuderforest that uses maps from OpenStreetMap.

    1. That is a very difficult question, all already answered in the “quick start” section. If you are really new, please do some of your own research and play around with the basic server management stuff first – Set up a simple HTML page, create a database, import dummy database, etc…

Leave a Comment

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