Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Geoips Provider Laravel Package

geocoder-php/geoips-provider

Geocoder provider for the geoips.com service, letting you resolve IP addresses into geographic coordinates and location data through the Geocoder PHP library's provider interface. A lightweight way to add GeoIPs-backed IP geolocation lookups to your PHP application.

View on GitHub
Deep Wiki
Context7

Getting Started

This package is abandoned as of 4.2.0. The upstream GeoIPs service has shut down its APIs, so the GeoIPs-backed driver no longer returns data. Treat 4.2.0 as a legacy pin, not a package to adopt.

If you are inheriting a project that already depends on it:

  1. Check what you actually have installed and which driver is configured:
    composer show --direct | grep -i geoip
    composer why <vendor>/<package>
    
  2. Inspect config/geoip.php (or equivalent) for the configured service/driver. Anything pointing at GeoIPs must be replaced or removed before the next deploy.
  3. Pin the exact version ("<vendor>/<package>": "4.2.0" or the last version that worked) so a future composer update does not silently change behaviour on an unmaintained dependency.
  4. Find every call site before touching configuration:
    grep -rn "GeoIP\|geoip\|getLocation\|country_code" app/ resources/ routes/ tests/
    

The first real use case is almost always "look up a visitor's country for currency/locale/redirect/compliance decisions." If that is the only use case, the cheapest migration is often not a like-for-like driver swap but moving the lookup behind your own interface and filling it with a maintained provider (MaxMind GeoLite2 via geoip2/geoip2, a CDN/edge header such as Cloudflare's CF-IPCountry, or a paid API). Do that before adding any new features on top of the abandoned package.

Implementation Patterns

Wrap it before you replace it. Introduce an application-owned contract now, even if the implementation still delegates to this package. This is the single highest-leverage change, because it makes the eventual removal a one-file diff:

// app/Contracts/GeoResolver.php
interface GeoResolver
{
    public function countryFor(string $ip): ?string;
}

// app/Services/LegacyGeoIpResolver.php
final class LegacyGeoIpResolver implements GeoResolver
{
    public function countryFor(string $ip): ?string
    {
        return cache()->remember("geo:{$ip}", now()->addDay(), function () use ($ip) {
            return GeoIP::getLocation($ip)?->country_code ?? null;
        });
    }
}

Bind the interface in a service provider, inject GeoResolver everywhere, and never let the facade leak into controllers, Blade views, or models.

Resolve at the edge of the request, store the result. Geo lookups are I/O. Resolve once during registration/checkout/first visit and persist the country on the user or order record. Subsequent reads should hit your database, not the resolver.

Use a fallback chain, not a single provider. A resilient resolver tries, in order: trusted edge header → local MaxMind database → cached last-known value → configured default. An abandoned driver belongs at the end of that chain, if anywhere, and only behind a short timeout.

Queue anything non-blocking. If you are enriching existing records with country data, do it in a job with retries and a dead-letter path. A shutdown upstream API turns a synchronous backfill into a fleet of hung requests.

Cache aggressively and key by IP + provider. Geo data changes slowly; API availability does not. A 24-hour cache both cuts latency and blunts the impact of the dead GeoIPs endpoint, since cached rows keep serving after the provider fails.

Test against a fake, not the network. Bind a stub GeoResolver returning fixed countries in your test suite. Never let feature tests reach a third-party Geo endpoint — with an abandoned provider, those tests are now permanently red or silently asserting on null.

Migration path, concretely: add the interface and binding (one PR, no behaviour change) → add a second implementation backed by MaxMind or edge headers → switch the binding via config → delete the legacy implementation and the Composer dependency. Each step is independently deployable.

Gotchas and Tips

  • The GeoIPs driver is dead, not degraded. Expect connection errors, timeouts, and null results — not stale-but-plausible data. Any code path that assumes a non-null location will now throw or, worse, silently write empty country codes. Audit for ->country_code on a possibly-null result and coerce explicitly.
  • null is a valid answer. Private/reserved IPs (10.0.0.0/8, 127.0.0.1, ::1), IPv6 addresses, and local development traffic will not resolve. Design for a nullable country and a documented default, and make sure local and CI environments never depend on a live lookup.
  • Provider swaps change the payload shape. iso_code, country_code, country, and countryCode are not interchangeable across drivers and versions. Normalise to a single two-letter ISO 3166-1 alpha-2 string at the boundary; everything downstream should speak only that.
  • Config caching bites. php artisan config:cache after editing config/geoip.php, or your change has no effect in production. This is the most common "I fixed it locally" failure with these packages.
  • Abandonment means no security patches and no PHP/Laravel compatibility fixes. Verify it installs on your PHP and Laravel versions and check composer audit for transitive advisories. Add a scheduled reminder to revisit the dependency; an unmaintained package tends to break on the next framework major, at the worst possible time.
  • Rate limits and 429s from third-party Geo APIs are easy to hit on high-traffic pages. Throttle, cache, and never call the resolver inside a loop or a Blade partial.
  • Extension point worth using: if you cannot remove the package immediately, most of these packages allow registering a custom service/driver via config or a container binding. Writing a thin custom driver that calls your chosen provider lets you keep the facade and call sites intact while swapping the backend — the fastest path off GeoIPs with the smallest blast radius.
  • Document the decision. Leave a short note in the repo (or an ADR) stating that the package is abandoned, which driver is in use, and what the replacement plan is. The next developer to run composer outdated will otherwise re-litigate this from scratch.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource