Skip to content

PHP Quickstart

Server-side: tile proxy, geocoding, downloads. Client-side maps run in browser via MapLibre.

Tile proxy (Laravel route)

php
// routes/api.php
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Http;

Route::get('/tiles/{z}/{x}/{y}.pbf', function ($z, $x, $y) {
    $key    = env('MFD_SRV_KEY');
    $secret = env('MFD_SRV_SECRET');
    $path   = "/tiles/$z/$x/$y.pbf";
    $ts     = (string) time();
    $sig    = hash_hmac('sha256', "GET\n$path\n$ts", $secret);

    $upstream = Http::withHeaders([
        'Authorization'    => "Bearer $key",
        'X-MFD-Timestamp'  => $ts,
        'X-MFD-Signature'  => $sig,
    ])->get("https://tiles.mapsfordevs.com$path");

    return response($upstream->body(), $upstream->status(), [
        'Content-Type'  => 'application/x-protobuf',
        'Cache-Control' => 'public, max-age=86400',
    ]);
});

Plain PHP with Guzzle

bash
composer require guzzlehttp/guzzle
php
<?php
use GuzzleHttp\Client;

function geocode(string $apiKey, string $query, ?string $country = null): array {
    $client = new Client(['timeout' => 10]);
    $params = ['q' => $query, 'limit' => 5];
    if ($country) $params['country'] = $country;

    $response = $client->get('https://api.mapsfordevs.com/geocode/forward', [
        'headers' => ['Authorization' => "Bearer $apiKey"],
        'query'   => $params,
    ]);
    $body = json_decode($response->getBody(), true);

    if (!($body['ok'] ?? false)) {
        throw new RuntimeException($body['error'] ?? 'mfd error');
    }
    return $body['items'] ?? [];
}

$results = geocode($_ENV['MFD_PUB_KEY'], '80 Sturdee Ave Rosebank', 'za');
foreach ($results as $r) echo "$r[lat], $r[lng] — $r[label]\n";

Symfony service

php
// src/Service/MapsForDevsClient.php
namespace App\Service;

use Symfony\Contracts\HttpClient\HttpClientInterface;

class MapsForDevsClient
{
    public function __construct(
        private HttpClientInterface $http,
        private string $apiKey
    ) {}

    public function geocode(string $query, ?string $country = null): array
    {
        $resp = $this->http->request('GET',
            'https://api.mapsfordevs.com/geocode/forward', [
                'headers' => ['Authorization' => 'Bearer ' . $this->apiKey],
                'query'   => array_filter(['q' => $query, 'country' => $country, 'limit' => 5]),
                'timeout' => 10,
            ]);
        $body = $resp->toArray(false);
        if (!($body['ok'] ?? false)) throw new \RuntimeException($body['error'] ?? 'mfd error');
        return $body['items'];
    }
}

Sign request (HMAC) helper

php
function signMFD(string $method, string $path, string $secret): array {
    $ts  = (string) time();
    $sig = hash_hmac('sha256', "$method\n$path\n$ts", $secret);
    return ['ts' => $ts, 'sig' => $sig];
}