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

Ip2Location Php Laravel Package

ip2location/ip2location-php

IP2Location PHP library for looking up IP addresses: country, region, city, coordinates, ZIP, ISP, domain, connection type, and more via BIN databases or the web service. Supports IPv4/IPv6 and works standalone or with Laravel.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the library and provision a database file — there is no Laravel service provider, facade, or config file to publish.

composer require ip2location/ip2location-php
  1. Get a BIN database. Download either the free LITE edition (e.g. DB1 LITE for country, DB3 LITE for city, DB11 LITE for all fields) or a commercial edition from ip2location.com. The library is only a reader; without a .BIN file new IP2Location($path) throws.
  2. Store it outside the web root. Put it in storage/app/ip2location/ and never commit it. LITE DB11 is tens of MB; commercial DBs are larger. Add a deploy/download step or mount it from a volume.
  3. Wire it into the container in AppServiceProvider::register():
use IP2Location\IP2Location;

$this->app->singleton(IP2Location::class, function () {
    return new IP2Location(storage_path(config('services.ip2location.bin')));
});
  1. First use case: a middleware or controller that resolves the visitor’s country to set currency/locale or block/redirect by region:
$record = app(IP2Location::class)->getAll(request()->ip());

if ($record && $record['countryCode'] === 'DE') {
    app()->setLocale('de');
}

Look first at the package README’s list of getCountry(), getCity(), getAll(), and the WebService class — those cover 90% of Laravel use cases (localization, geo-blocking, currency, analytics enrichment, fraud checks). If you want a Laravel-native wrapper instead of hand-wiring, check whether ip2location/ip2location-laravel fits your version before building your own.

Implementation Patterns

Wrap it in your own service. Because the package has no Laravel integration, create App\Services\GeoIpService that owns IP normalization, the IP2Location instance, and caching. Inject that service everywhere instead of the raw class. This gives you one place to swap providers later (MaxMind, Cloudflare headers, a hosted API) and one place to fake in tests.

Resolve the real client IP, not request()->ip() blindly. Behind load balancers, Cloudflare, or Laravel Octane, the socket IP is often the proxy. Configure TrustProxies correctly and consider a helper that prefers CF-Connecting-IP, then X-Forwarded-For, then request()->ip(). Reject private/reserved ranges (127.0.0.1, 10/8, 172.16/12, 192.168/16, ::1) before lookup; the library returns no usable record for them.

Cache per IP. BIN lookups are fast but not free, and the same IPs recur. Use Cache::remember("geoip:{$ip}", now()->addDay(), fn () => $service->lookup($ip)). For authenticated users, cache on user_id instead. Invalidation is easy because IP-to-location changes slowly.

Middleware for locale/currency/geo-restriction. Resolve the country once per request in middleware, store it on the request ($request->attributes->set('geo', $record)) or in a scoped container binding, then let controllers, Blade/Inertia shared props, and form requests read it. Avoid calling the library repeatedly in views.

Batch enrichment in jobs. For imports, order backfills, or analytics pipelines, inject the service into a queued job and chunk records. Use getAll() once per IP rather than ten separate getter calls. Keep the singleton alive within a worker; for very large imports consider one job per chunk so memory and retries stay predictable.

Choose the right database edition. DB1 (country) is small and fast; DB3 adds region/city; DB11 adds ISP, domain, timezone, mobile, usage type, IAB category. Don’t load DB11 if you only need country — the file size and deploy cost matter. If you need multiple editions, create separate named singletons and pick per feature.

Use the WebService class as a fallback. IP2Location\WebService calls the hosted API with an API key. Good when you cannot ship a BIN file, need fields your local DB lacks, or want a failover. Put the key in config/services.php and env, and cache aggressively because API plans have quotas.

Validation and form requests. Country-aware validation rules (phone format, postal code, tax/VAT rules) can consume the resolved country. Resolve geo data in a base form request or middleware so validation stays declarative.

Testing. Bind a fake implementation of your GeoIpService in tests. For integration tests against the real BIN, use known stable IPs and assert only fields your edition actually provides. Never assert city-level accuracy from the LITE database — it is deliberately coarse.

Gotchas and Tips

  • It is not a Laravel package. No auto-discovery, no config/ip2location.php, no facade. Everything above is manual wiring; budget for that or use a community wrapper.
  • Path handling: use storage_path() or base_path() with a config value, never public_path(). The BIN file must be readable by the PHP user and excluded from git. On containerized deploys, download it during build or mount it; otherwise the constructor throws on first request.
  • Singleton vs. re-instantiation: constructing IP2Location opens the file. Register it as a singleton to avoid reopening per lookup. Under Octane, a long-lived singleton keeps a file handle across requests — if you replace the BIN during a deploy, restart workers or make the service re-open on file mtime change.
  • IPv4 vs. IPv6: IPv6 needs an IPv6 BIN database. If you only ship IPv4, IPv6 visitors resolve to nothing. Detect IP type and fall back gracefully or use the WebService.
  • Private and invalid IPs return false/empty. Always null-check the result before reading array keys; a missing countryCode in a Blade template is a common source of notices.
  • Field names vary by edition and by API surface. The procedural/legacy API and getAll() can expose different key names (countryCode vs. country_code depending on version and whether you use the WebService). Read the README for the exact keys of your installed version and edition, and normalize in your wrapper.
  • Proxy headers are the #1 accuracy bug. A geo-block that blocks your own office because it sees the load balancer’s IP is a classic. Configure TrustProxies and test from a real external IP, not localhost.
  • License and storage terms: commercial BIN files require a license; LITE is free but less accurate. Check whether your plan permits storing resolved geolocation data alongside user records.
  • Database freshness: IP allocations change monthly. Build a refresh process (scheduled download or manual version bump) and record the database version (getDatabaseVersion() if available) so you can debug stale results.
  • Cache keys must include the database version. If you refresh the BIN but keep cached lookups, you will serve old countries. Include a version or deployment hash in cache keys, or flush the geo cache on deploy.
  • Do not call the library in a loop over a large collection in a controller. Move enrichment to a job and use getAll() once per IP. For high-volume analytics, consider a columnar/offline join rather than per-request PHP lookups.
  • Extension point: wrap the library behind an interface (GeoLocator) with methods you actually use (country, city, timezone, coordinates). That keeps your app independent of IP2Location’s array shapes and lets you test, swap providers, and add caching without touching call sites.
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