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:
- A database table to record the last known locations.
- PHP library and endpoint to accept and manage the location updates.
- A webpage or application to send the rider’s current GPS location to the server.
- 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
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
- Create a database and import the
1-database.sql
file. - Change the database settings in
2a-core.php
to your own. 3-track.html
is the client/rider tracking page,4-admin.html
is the demo admin page. Captain Obvious – Usehttp://
notfile://
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
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
<?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
<?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:
|
get | Get the last known location of a given rider. Parameters:
|
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
<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
<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
- The Javascript geolocation API
- Need Maps?
Here’s a tutorial that I did on MapBox if you are interested.
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!
thanks a lot
worst
Dear genius (and future geniuses), please kindly share with us more of your superior intelligence on what is “worst” – That the rest of us foolish humans may strive to become better.
https://code-boxx.com/faq/#nolike
Anyone with the front end template of a gps tracking website? collinsmurimi1234@gmail.com
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.
Thanks for the code
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.
thank lot man you saved my life
Hello,
first of all : thanks 4 sharing this project. How can I add an openstreet Map ?
Best,
Amin
Edit – OpenStreetMap does not provide “direct end-user service”. Look for other map providers such as Mapbox and Thnuderforest that uses maps from OpenStreetMap.
how do I run the code on xamp
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…
thank you very much
thanks for sharing this
thanks a lot for your time and excellent explanation