PHP
Zip Code Distance
Geolocation
Distance Calculation
Programming Tutorial

Calculating distance between zip codes in PHP

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Calculating distance between ZIP codes in PHP is a two-step problem: map each ZIP to coordinates, then compute distance between points. Many implementations fail because they skip data quality checks or confuse straight-line distance with travel distance. A robust solution chooses the right distance model for the business requirement and validates missing ZIP inputs explicitly.

ZIP Codes Need Coordinate Data First

ZIP values are identifiers, not geographic coordinates. You need latitude and longitude from a trusted dataset or geocoding service.

Simple in-memory example:

php
1<?php
2
3$zipToCoord = [
4    '10001' => ['lat' => 40.7506, 'lon' => -73.9972],
5    '60601' => ['lat' => 41.8864, 'lon' => -87.6186],
6    '94105' => ['lat' => 37.7898, 'lon' => -122.3942],
7];

In production, this mapping usually lives in a database table with periodic refresh from a reliable geodata source.

Use the Haversine Formula for Straight-Line Distance

Haversine computes great-circle distance, which is suitable for proximity ranking and rough radius checks.

php
1<?php
2
3function haversineKm(float $lat1, float $lon1, float $lat2, float $lon2): float
4{
5    $earthRadiusKm = 6371.0;
6
7    $dLat = deg2rad($lat2 - $lat1);
8    $dLon = deg2rad($lon2 - $lon1);
9
10    $a = sin($dLat / 2) ** 2
11       + cos(deg2rad($lat1)) * cos(deg2rad($lat2))
12       * sin($dLon / 2) ** 2;
13
14    $c = 2 * atan2(sqrt($a), sqrt(1 - $a));
15    return $earthRadiusKm * $c;
16}
17
18echo round(haversineKm(40.7506, -73.9972, 37.7898, -122.3942), 2) . " km\n";

This value is straight-line distance, not driving distance.

Build a Safe ZIP Distance Helper

Wrap lookup and distance calculation into a single function that handles unknown ZIP values cleanly.

php
1<?php
2
3function zipDistanceKm(string $zipA, string $zipB, array $zipToCoord): ?float
4{
5    if (!isset($zipToCoord[$zipA]) || !isset($zipToCoord[$zipB])) {
6        return null;
7    }
8
9    $a = $zipToCoord[$zipA];
10    $b = $zipToCoord[$zipB];
11
12    return haversineKm($a['lat'], $a['lon'], $b['lat'], $b['lon']);
13}
14
15$result = zipDistanceKm('10001', '60601', $zipToCoord);
16echo $result === null ? "Unknown ZIP\n" : round($result, 2) . " km\n";

Returning null is better than returning zero for missing data, because zero can be misinterpreted as a valid distance.

Convert Units Predictably

Keep one internal computation unit and convert only for presentation.

php
1<?php
2
3function kmToMiles(float $km): float
4{
5    return $km * 0.621371;
6}
7
8$km = 100.0;
9echo round(kmToMiles($km), 2) . " miles\n";

This avoids mixed-unit bugs in reporting and downstream calculations.

Batch Distance Queries for Search Workloads

For store-locator or dispatch screens, you often compute distance from one origin ZIP to many destination ZIPs.

php
1<?php
2
3$origin = '10001';
4$destinations = ['60601', '94105', '99999'];
5
6foreach ($destinations as $zip) {
7    $distance = zipDistanceKm($origin, $zip, $zipToCoord);
8    if ($distance === null) {
9        echo "$zip: unavailable\n";
10        continue;
11    }
12
13    echo "$zip: " . round($distance, 1) . " km\n";
14}

You can sort the resulting list by distance to implement nearest-location features.

When To Use Routing APIs Instead

Haversine ignores roads, traffic, and barriers. If business logic depends on travel time or route distance, call a routing API instead.

Recommended approach:

  • Geocode postal codes to points.
  • Query route distance and duration.
  • Cache common origin-destination results.

Routing APIs are slower and cost money, but they are more realistic for logistics and ETA calculations.

Caching and Data Freshness

Performance and cost improve significantly with caching.

  • Cache ZIP-to-coordinate lookups.
  • Cache popular distance pairs.
  • Set refresh policy for geodata updates.

This is especially important for high-traffic applications with repeated geographic lookups.

Common Pitfalls

  • Trying to calculate distance directly from ZIP strings. Fix: map ZIP values to coordinates first.
  • Treating straight-line distance as driving distance. Fix: use routing APIs when route realism is required.
  • Returning zero for unknown ZIP inputs. Fix: return explicit missing result like null.
  • Mixing miles and kilometers in one computation chain. Fix: standardize on one base unit and convert at output.
  • Ignoring cache strategy for repeated requests. Fix: cache lookup and distance results with sensible expiration.

Summary

  • ZIP distance in PHP requires coordinate lookup plus distance math.
  • Haversine is a practical default for straight-line estimates.
  • Validate unknown ZIP inputs explicitly to prevent silent errors.
  • Use routing APIs when travel distance or ETA matters.
  • Add caching and unit discipline for reliable, scalable implementations.

Course illustration
Course illustration

All Rights Reserved.