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.
QUICK NOTES
- Create a database and import
1-database.sql
. - 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://
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.
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
$_TRACK = new Track()
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 To E) There are only 3 GPS rider functions!
update()
records a rider’s GPS coordinates.get()
returns a rider’s last known coordinates.getAll()
returns all riders’ last known coordinates.
- (G & H) Self-explanatory. Remember to change the database settings.
AJAX ENDPOINT
<?php
// (A) INIT
require "2a-core.php";
if (isset($_POST["req"])) { 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 by 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 are ready, we have to build a simple client-side tracker that will update the server of the rider’s current locations.
JAVASCRIPT GPS TRACKER
<!-- (A) YOUR MAP HERE -->
<div id="display"></div>
<script>
var track = {
// (B) 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.
// (C) INIT
init : () => {
// (C1) GET HTML DISPLAY
track.display = document.getElementById("display");
// (C2) CHECK GPS SUPPORT + START TRACKING
if (navigator.geolocation) {
track.update();
track.timer = setInterval(track.update, track.delay);
} else { track.display.innerHTML = "Geolocation not supported!"; }
},
// (D) UPDATE CURRENT LOCATION TO SERVER
update : () => {
navigator.geolocation.getCurrentPosition(
// (D1) OK - SEND GPS COORDS TO SERVER
(pos) => {
// 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);
// AJAX FETCH
fetch("2b-ajax-track.php", { method:"POST", body:data })
.then(res => res.json()).then((res) => {
if (res.status==1) {
track.display.innerHTML = Date.now() +
" | Lat: " + pos.coords.latitude +
" | Lng: " + pos.coords.longitude;
} else { track.display.innerHTML = res.message; }
}).catch((err) => { console.error(err); });
},
// (D2) ERROR
(err) => {
console.error(err);
track.display.innerHTML = err.message;
clearInterval(track.timer);
}
);
}
};
window.addEventListener("DOMContentLoaded", track.init);
</script>
This seems massive at first, but do a quick trace and this is very straightforward:
- An HTML
<div>
to display your map and information. - Settings for the tracker.
- On window load, create a timer and start tracking on intervals.
- Get the GPS coordinates and upload them to the server.
Yep, that’s the gist of it. 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
<!-- (A) YOUR MAP HERE -->
<div id="map"></div>
<script>
var track = {
// (B) PROPERTIES
map : null, // HTML map
delay : 10000, // Delay between location refresh
// (C) INIT
init : () => {
track.map = document.getElementById("map");
track.show();
setInterval(track.show, track.delay);
},
// (D) GET DATA FROM SERVER AND UPDATE MAP
show : () => {
// (D1) DATA
var data = new FormData();
data.append("req", "getAll");
// (D2) AJAX FETCH
fetch("2b-ajax-track.php", { method:"POST", body:data })
.then(res => res.json()).then((res) => {
if (res.status==1) { for (let rider of res.message) {
var row = document.createElement("div");
row.innerHTML = "Rider ID " + rider.rider_id +
" | Lng " + rider.track_lng +
" | Lat " + rider.track_lat +
" | Time " + rider.track_time;
track.map.appendChild(row);
}} else { track.map.innerHTML = res.message; }
}).catch((err) => { console.error(err); });
}
};
window.addEventListener("DOMContentLoaded", track.init);
</script>
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
- Javascript Geolocation API – MDN
- 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!
Hi, thanks a lot for sharing.
I think i have solved the devices reporting and storing coordinates and date to database. I wish you to comment to me, how the easier way is to just “show” or “view” devices track.
I don’t quite catch your question… I shall assume that you have added a “date-time” column to the
gps_track
table and want to show the travel history. I will personally add anothertrip_id
togps_track
, makes things a lot easier to group.SELECT * FROM `gps_track` WHERE `rider_id`=? AND `trip_id`=?
SELECT * FROM `gps_track` ORDER BY `trip_id`, `date`
Otherwise, I cannot provide further help for your personal project. Good luck!
https://code-boxx.com/faq/#help “No free project consultation”
Hello, I testing the app and receive this error in
4-admin.html
SyntaxError: Unexpected token S in JSON at position 0
Thank you for your help, nice code!!
Not getting any errors here. “Unable to parse JSON” can be anything – Your own customizations broke it, your browser is not parsing the data correctly, you are pointing to the wrong server-side URL, your server is not generating JSON correctly, etc… Good luck.
Hi, in my project I need to have the last name, first name .. of my users, how can I send last name, first name of my users already in a database in that of gps_track? Thank you for your help
Study how user login and sessions work, either by:
1) Good old PHP session – https://code-boxx.com/simple-login-php-mysql/
2) Or JWT – https://code-boxx.com/jwt-login-authentication-php-mysql/
That is the only piece of advice I can give for your personal project. Good luck. https://code-boxx.com/faq/#help
thank you sooooo much 👍
Thank for sharing the code. I would like to know how to get the exact location of the client device such as the phone or pc But this one seam to pick the GPS of the server not the end device.
1) Access 3-track.html on your smartphone.
2) Run away from your server as far as possible.
3) Install range extenders on the street if your WIFI coverage is not wide enough. 😆
This is a new level of “lost beyond hope”. Go hire a good full-stack developer if you cannot figure out the heads and tails. Good luck.
can you guide me how to track multiple employees and store all employee track record in db and at any time want to see where he gone
Create a new gps_history table and modify function update() to save the history.
Good luck. https://code-boxx.com/faq/#help
Thaaanks, this is a very good start.
thanks a lot