Runtime Driver
You can override the configured driver at runtime using the driver() method. This returns a new GeoIp instance with the specified driver — the default singleton remains unchanged.
Basic Usage
use ArielMejiaDev\GeoIp\Facades\GeoIp;
// Use ip-api for this lookup, regardless of the configured default
GeoIp::driver('ip-api')->lookup('8.8.8.8');With Quick Lookups
All quick lookup methods are available on the returned instance:
GeoIp::driver('maxmind')->country('8.8.8.8'); // 'United States'
GeoIp::driver('ipinfo')->countryCode('8.8.8.8'); // 'US'
GeoIp::driver('ip-api')->timezone('8.8.8.8'); // 'America/Los_Angeles'
GeoIp::driver('ip-api')->coordinates('8.8.8.8'); // ['latitude' => ..., 'longitude' => ...]With the Fluent API
Chain driver() with the fluent API for full expressiveness:
GeoIp::driver('maxmind')->of('8.8.8.8')
->whenCountry('US', fn ($ip) => applyDomesticRates())
->toArray();
GeoIp::driver('ip-api')->fromRequest()->city();Supported Drivers
Pass any supported driver name: dbip, maxmind, ip-api, ipinfo, or null.
// Use the null driver in specific scenarios
GeoIp::driver('null')->lookup('8.8.8.8');An InvalidArgumentException is thrown for unsupported driver names.
When to Use
- Comparing results across multiple providers for the same IP
- Fallback logic — try a local database first, then hit an API
- Testing — switch to the
nulldriver without changing config
Example: Cross-Driver Verification
The following test uses a University of Cincinnati IP (129.137.1.1, near Cincinnati Union Terminal) to verify that two independent drivers — a local database and a remote API — resolve the same address consistently:
use ArielMejiaDev\GeoIp\GeoIp;
it('resolves a Cincinnati IP similarly with dbip and ip-api drivers', function () {
$cincinnatiIp = '129.137.1.1';
$geoip = app(GeoIp::class);
$dbip = $geoip->driver('dbip')->lookup($cincinnatiIp);
$ipApi = $geoip->driver('ip-api')->lookup($cincinnatiIp);
// Both should resolve successfully.
expect($dbip->isResolved())->toBeTrue()
->and($ipApi->isResolved())->toBeTrue();
// Both should agree on country.
expect($dbip->countryCode)->toBe('US')
->and($ipApi->countryCode)->toBe('US');
// Both should agree on state.
expect($dbip->region)->toBe('Ohio')
->and($ipApi->region)->toBe('Ohio');
// Both should agree on city.
expect($dbip->city)->toBe('Cincinnati')
->and($ipApi->city)->toBe('Cincinnati');
// Both should agree on timezone.
expect($dbip->timezone)->toBe('America/New_York')
->and($ipApi->timezone)->toBe('America/New_York');
});This pattern is useful for auditing data quality, validating a new driver before switching, or ensuring consistent results across providers.