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

Resolving the geolocator

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

Geolocator::lookup('8.8.8.8');                     // facade
app(GeolocatorContract::class)->lookup('8.8.8.8'); // contract
app('geolocator')->lookup('8.8.8.8');              // container alias

All three resolve the same manager instance. The contract is imported under an as alias because the facade and the contract share their short name. The package also registers a global Geolocator facade alias through extra.laravel.aliases, so the shortest entry point needs no import:

\Geolocator::lookup('8.8.8.8');

Looking up an address

$location = Geolocator::lookup('8.8.8.8');        // country, city and ASN
$country = Geolocator::lookupCountry('8.8.8.8');  // country only
$city = Geolocator::lookupCity('8.8.8.8');        // city only
$asn = Geolocator::lookupAsn('8.8.8.8');          // ASN only

Each returns a LocationResult, with the editions you did not ask for left as null:

$location->ipAddress;                  // '8.8.8.8'
$location->country?->countryCode;      // e.g. 'US'
$location->country?->countryName;      // e.g. 'United States'
$location->country?->getCoordinates(); // e.g. ['latitude' => 37.09, 'longitude' => -95.71]
$location->city?->city;                // e.g. 'Ashburn'
$location->city?->state1;              // e.g. 'Virginia'
$location->city?->timezone;            // e.g. 'America/New_York'
$location->asn?->asn;                  // e.g. 15169
$location->asn?->organization;         // e.g. 'Google LLC'

$location->hasResults();               // true when any edition returned data
$location->toArray();

lookup() reads all three editions, so it needs the country, city and ASN files to exist even when you only read the country from the result. The edition-specific methods read one file each; see Installation for where those files come from and Troubleshooting for what a missing one does.

Empty results

Private, reserved and unparseable addresses return no records, so the result is empty:

Geolocator::lookup('192.168.1.1')->hasResults(); // false
(string) Geolocator::lookup('192.168.1.1');      // 'Unknown Location'

An empty result is a normal answer, not an error — check hasResults() rather than wrapping the call in a try/catch. Note that it does not mean the database is absent: when the file cannot be opened, the lookup throws even for 192.168.1.1.

Resolving the current request

The package registers a geolocate macro on the request:

Route::get('/location', function (Illuminate\Http\Request $request) {
    return $request->geolocate()->toArray();
});

It resolves the client address with $request->ip() and falls back to '0.0.0.0' when the request carries no address at all. Pass your own default as the first argument, and select an edition or a driver with the other two:

$request->geolocate('127.0.0.1');        // custom default address
$request->geolocate(edition: 'country'); // one edition: all (default), country, city or asn
$request->geolocate(driver: 'custom');   // a driver other than the configured default

The edition picks the method the macro calls, so edition: 'city' is lookupCity().

X-Forwarded-For is only consulted when the request comes from a trusted proxy. Configure this with Laravel's TrustProxies middleware, otherwise the header is ignored and the proxy's own address is used — and the driver resolves a private address to an empty result.

Clone this wiki locally