Skip to content

Custom drivers

Nick Hamnett edited this page Sep 29, 2026 · 1 revision

Implement SameOldNick\Geolocator\Contracts\Geolocator and register it with extend():

use SameOldNick\Geolocator\Contracts\Geolocator as GeolocatorContract;
use SameOldNick\Geolocator\DTOs\LocationResult;
use SameOldNick\Geolocator\Facades\Geolocator;

class MyGeolocator implements GeolocatorContract
{
    public function lookup(string $ip): LocationResult { /* ... */ }

    public function lookupCountry(string $ip): LocationResult { /* ... */ }

    public function lookupCity(string $ip): LocationResult { /* ... */ }

    public function lookupAsn(string $ip): LocationResult { /* ... */ }
}

Geolocator::extend('my-driver', fn ($app) => new MyGeolocator());

Select it with GEOLOCATOR_DRIVER=my-driver, or by setting geolocator.driver in the config file. The geolocate request macro can also be pointed at it per call: $request->geolocate(driver: 'my-driver').

How a driver name is resolved

A name is resolved either by a registered creator (as above) or by a createXDriver() method on the manager. Any other name throws InvalidArgumentException: Driver [x] not supported. — the container is not consulted, so a container binding alone will not register a driver.

Replace, don't fork

Before writing a driver, check whether the shipped one can be extended instead: the reader providers in SameOldNick\Geolocator\Drivers\IPLocationDB\Providers are the seam for changing how a database file is opened, and the Support helpers (CountryHelper, IPAddressHelper) cover the country-code and address handling. See Testing for swapping either of them in a test.

Clone this wiki locally