PHPackages                             ilmlv/php-geoip - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. ilmlv/php-geoip

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

ilmlv/php-geoip
===============

IP geolocation lookup and response formatting for MaxMind GeoLite2, DB-IP, IPLocate, IPinfo and IP2Location databases.

v1.0.0-beta.1(1mo ago)0279↑350%MITPHP &gt;=7.2

Since Jun 21Compare

[ Source](https://github.com/IlmLV/php-geoip)[ Packagist](https://packagist.org/packages/ilmlv/php-geoip)[ Docs](https://github.com/IlmLV/php-geoip)[ RSS](/packages/ilmlv-php-geoip/feed)WikiDiscussions Synced 2w ago

READMEChangelogDependencies (3)Versions (3)Used By (0)

 [![php-geoip logo](assets/logo.svg)](assets/logo.svg)

PHP GeoIP
=========

[](#php-geoip)

 A lightweight PHP library for IP geolocation lookups and response formatting — one API across a zero-config remote service, MaxMind GeoLite2, DB-IP, IPLocate, IPinfo and IP2Location.

 [![CI](https://github.com/IlmLV/php-geoip/actions/workflows/ci.yml/badge.svg)](https://github.com/IlmLV/php-geoip/actions/workflows/ci.yml) [![Code Coverage](https://camo.githubusercontent.com/b2ca627085b02285154c4b1a13fdec5aa772f0deeeb99aa695dbdef1789415a6/68747470733a2f2f636f6465636f762e696f2f67682f496c6d4c562f7068702d67656f69702f67726170682f62616467652e737667)](https://codecov.io/gh/IlmLV/php-geoip) [![Latest Version](https://camo.githubusercontent.com/149d5d222179c616fcc3a83d2f95ffa1fc406f20d89bb304c44b83c2430d7e3e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f696c6d6c762f7068702d67656f69702e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/ilmlv/php-geoip) [![Total Downloads](https://camo.githubusercontent.com/f74db15968d9233f4070bc39809828ca635f9d04391f0bad6cac0cb3ca88302b/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f696c6d6c762f7068702d67656f69702e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/ilmlv/php-geoip) [![PHP Version](https://camo.githubusercontent.com/42176e48e43718b95a2e187929a7d5eb8b47abd71ddf17206a32eaa49144a068/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f696c6d6c762f7068702d67656f69702e7376673f7374796c653d666c61742d737175617265)](https://php.net/) [![License](https://camo.githubusercontent.com/5f884d8a33777adbea8247dd791fc45f7b4a9ab12b7429a6db1c2c1404afc501/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f696c6d6c762f7068702d67656f69702e7376673f7374796c653d666c61742d737175617265)](LICENSE)

---

Features
--------

[](#features)

- **Zero config by default** — works out of the box via the remote `ip.serviss.it` service, no database to download.
- **Simple API** — resolve an IP to a structured array with a single `locate()` call.
- **Multiple data sources** — the remote service, MaxMind GeoLite2, DB-IP, IPLocate, IPinfo (MMDB) and IP2Location (BIN), behind one provider interface.
- **City &amp; ASN data** — country, region, city, coordinates, timezone, and the originating organisation.
- **Flexible output** — render results as JSON or plain text, or pluck a single attribute.
- **Command line ready** — a `geoip` binary for lookups straight from the shell.
- **License-clean** — ships no database; you supply your own for local lookups, and the library surfaces each source's required attribution.
- **Lean dependencies** — only the official `geoip2/geoip2` reader. PHP 7.2+.

Table of contents
-----------------

[](#table-of-contents)

- [Installation](#installation)
- [Obtaining a database](#obtaining-a-database)
- [Usage](#usage)
- [Database providers](#database-providers)
- [Result schema](#result-schema)
- [Error handling](#error-handling)
- [Command line](#command-line)
- [Examples](#examples)
- [Requirements](#requirements)
- [License &amp; attribution](#license--attribution)

Installation
------------

[](#installation)

```
composer require ilmlv/php-geoip
```

Obtaining a database
--------------------

[](#obtaining-a-database)

You don't need one to get started: by default the library queries the remote **ip.serviss.it** service (see [Database providers](#database-providers)). For local, offline or high-volume lookups, use one of the database providers instead.

This package **bundles no database** — database licenses vary by source and most require keeping the data current. The included `geoip-update` downloader supports several sources:

```
# MaxMind GeoLite2 (free account + license key required)
MAXMIND_LICENSE_KEY=your_key vendor/bin/geoip-update --dir=./data

# DB-IP Lite — no API key, CC BY 4.0 (just attribute db-ip.com)
vendor/bin/geoip-update --source=dbip --dir=./data

# Any direct .mmdb / .mmdb.gz URL (e.g. an IPLocate or IPinfo tokenised link)
vendor/bin/geoip-update --source=url --url='https://…/file.mmdb.gz' --dir=./data
```

For scheduled MaxMind updates, the official [`geoipupdate`](https://github.com/maxmind/geoipupdate) tool is also a good option. See [Database providers](#database-providers) for which sources need a key and how to attribute them.

Usage
-----

[](#usage)

```
use IlmLV\GeoIp\GeoIpLocator;
use IlmLV\GeoIp\ResponseFormatter;

// Zero config: no argument → looks up via the remote ip.serviss.it service.
$locator = new GeoIpLocator();

// Or read a local MaxMind GeoLite2 (or compatible) database:
$locator = new GeoIpLocator(
    '/path/to/GeoLite2-City.mmdb',
    '/path/to/GeoLite2-ASN.mmdb'   // optional — enables the `organisation` field
);

$result = $locator->locate('8.8.8.8');

$formatter = new ResponseFormatter();
echo $formatter->toJson($result);                   // JSON string
echo $formatter->toPlainText($result);              // "Pretty-Key: value" lines
echo $formatter->pluck($result, 'country-iso-code'); // "US"
```

To include a `country.flag.url` in the result, pass a base URL as the third constructor argument:

```
$locator = new GeoIpLocator($cityDb, $asnDb, '//cdn.example.com/flags');
```

Database providers
------------------

[](#database-providers)

By default (no constructor argument) the library uses the **remote** provider, which queries the public `ip.serviss.it` service — no database required. To read a local database instead, pass a provider to `GeoIpLocator::withProvider()`. Every provider returns the same [result schema](#result-schema), so the rest of your code is unchanged.

```
use IlmLV\GeoIp\GeoIpLocator;
use IlmLV\GeoIp\Provider\ServissItProvider;
use IlmLV\GeoIp\Provider\MmdbCityProvider;
use IlmLV\GeoIp\Provider\IpinfoLiteProvider;
use IlmLV\GeoIp\Provider\IP2LocationProvider;

// Remote ip.serviss.it (default; equivalent to `new GeoIpLocator()`)
GeoIpLocator::withProvider(new ServissItProvider());

// MMDB family (MaxMind-reader compatible). Optional 2nd arg = ASN database.
GeoIpLocator::withProvider(MmdbCityProvider::dbip('data/dbip-city-lite.mmdb'));
GeoIpLocator::withProvider(MmdbCityProvider::iplocate('data/iplocate-city.mmdb'));
GeoIpLocator::withProvider(MmdbCityProvider::maxmind('data/GeoLite2-City.mmdb', 'data/GeoLite2-ASN.mmdb'));

// IPinfo Lite (flat MMDB schema — country/continent/ASN only)
GeoIpLocator::withProvider(new IpinfoLiteProvider('data/ipinfo-lite.mmdb'));

// IP2Location BIN (needs ip2location/ip2location-php; see Requirements)
GeoIpLocator::withProvider(new IP2LocationProvider('data/IP2LOCATION-LITE-DB11.BIN'));

$locator->attribution(); // the source's required attribution string, or null
```

SourceFormatAPI keyLicenseFields**ip.serviss.it** (default)remote HTTPno— (depends on the service's source)per the service (city, region, country, coords, tz, ASN)**MaxMind GeoLite2**MMDByesCC BY-SA 4.0city, region, country, coords, tz, ASN**DB-IP Lite**MMDBnoCC BY 4.0 †city, region, country, coords**IPLocate.io**MMDByes (free)CC BY-SA 4.0 †city, region, country, coords, ASN**IPinfo Lite**MMDByes (token)CC BY-SA 4.0 †country, continent, ASN**IP2Location LITE**BINyes (free)CC BY-SA 4.0 †city, region, country, coords, tzThe **remote provider** makes an outbound HTTPS call per lookup to a fixed endpoint (`https://ip.serviss.it`) and needs no database; it's ideal for getting started and low-volume use. For offline use, high volume, or to avoid sending IPs to a third party, choose a local provider. It throws `RemoteException` on a network/service failure.

† These sources require their attribution to be displayed wherever their data appears. `GeoIpLocator::attribution()` returns the exact snippet (the CLI prints it automatically; the web-endpoint [example](#examples) shows how to render it). See [License &amp; attribution](#license--attribution).

Result schema
-------------

[](#result-schema)

`locate()` returns a normalised array. Missing values are `null`.

```
[
    'ip'           => '8.8.8.8',
    'organisation' => 'GOOGLE',
    'city'         => ['name' => null],
    'country'      => [
        'name'                 => 'United States',
        'iso_code'             => 'US',
        'is_in_european_union' => false,
        'flag'                 => ['emoji' => '🇺🇸'],
    ],
    'continent'    => ['name' => 'North America', 'code' => 'NA'],
    'region'       => ['name' => null, 'iso_code' => null],
    'location'     => ['latitude' => 37.751, 'longitude' => -97.822],
    'zip_code'     => null,
    'time_zone'    => 'America/Chicago',
    'metro_code'   => null,
]
```

`ResponseFormatter::pluck()` accepts any nested or flattened key, case- and separator-insensitive — `country-iso-code`, `country_iso_code`, and `country`all resolve.

Error handling
--------------

[](#error-handling)

All exceptions implement the `IlmLV\GeoIp\Exception\GeoIpException` marker interface, so the whole package can be caught in one block.

ConditionExceptionMalformed IP address`InvalidIpException`IP absent from the database`AddressNotFoundException`Unknown attribute in `pluck()``UnknownAttributeException`Missing optional provider package`MissingDependencyException`Remote provider network/service error`RemoteException`Command line
------------

[](#command-line)

The package installs a `geoip` binary at `vendor/bin/geoip` for lookups from the shell. With no `--provider`, it uses the remote `ip.serviss.it` service (zero setup):

```
vendor/bin/geoip 8.8.8.8
vendor/bin/geoip 8.8.8.8 --format=json
vendor/bin/geoip 8.8.8.8 --what=country-iso-code   # → US
```

For a local database, pick a provider:

```
vendor/bin/geoip 8.8.8.8 --provider=mmdb --db=./data/GeoLite2-City.mmdb
vendor/bin/geoip 8.8.8.8 --provider=dbip --db=./data/dbip-city-lite.mmdb
```

OptionDescription`--format=``plain` (default) or `json`.`--what=`Print a single attribute, e.g. `country-iso-code`.`--provider=``serviss` (default, remote), `mmdb`, `dbip`, `iplocate`, `ipinfo`, `ip2location` (or `$GEOIP_PROVIDER`).`--db=`Primary database path (or `--city-db` / `$GEOIP_CITY_DB`).`--asn-db=`ASN `.mmdb` for `organisation` (or `$GEOIP_ASN_DB`).`--ip2location=`Path to an IP2Location `.BIN` (with `--provider=ip2location`).`--flag-base-url=`Base URL for flag SVGs; adds `country.flag.url`.`-h`, `--help`Show usage.Database paths default to `./data`. Exit codes: `0` success, `1` usage/runtime error, `2` IP not found.

Examples
--------

[](#examples)

Short, copy-pasteable recipes. They use the zero-config remote provider unless a database path is given.

### Look up an IP

[](#look-up-an-ip)

```
use IlmLV\GeoIp\GeoIpLocator;

$result = (new GeoIpLocator())->locate('8.8.8.8');
echo $result['country']['name'];      // "United States"
echo $result['country']['iso_code'];  // "US"
echo $result['time_zone'];            // "America/Chicago"
```

### Format the result

[](#format-the-result)

```
use IlmLV\GeoIp\GeoIpLocator;
use IlmLV\GeoIp\ResponseFormatter;

$result = (new GeoIpLocator())->locate('8.8.8.8');
$format = new ResponseFormatter();

echo $format->toJson($result);                    // JSON string
echo $format->toPlainText($result);               // "Country-Name: United States\n…"
echo $format->pluck($result, 'country-iso-code'); // "US"  (single field)
```

### Read a local database

[](#read-a-local-database)

```
use IlmLV\GeoIp\GeoIpLocator;

// MaxMind GeoLite2 (City + optional ASN). Download with `vendor/bin/geoip-update`.
$result = (new GeoIpLocator('data/GeoLite2-City.mmdb', 'data/GeoLite2-ASN.mmdb'))
    ->locate('8.8.8.8');
```

```
use IlmLV\GeoIp\GeoIpLocator;
use IlmLV\GeoIp\Provider\MmdbCityProvider;

// DB-IP Lite (no API key). `attribution()` then returns the link you must show.
$locator = GeoIpLocator::withProvider(MmdbCityProvider::dbip('data/dbip-city-lite.mmdb'));
$result  = $locator->locate('8.8.8.8');
echo $locator->attribution(); // IP Geolocation by DB-IP
```

### Handle errors

[](#handle-errors)

```
use IlmLV\GeoIp\GeoIpLocator;
use IlmLV\GeoIp\Exception\GeoIpException;

try {
    $result = (new GeoIpLocator())->locate($ip);
} catch (GeoIpException $e) {
    // Covers invalid IP, address-not-found and remote failures in one catch.
    echo 'Lookup failed: ' . $e->getMessage();
}
```

### A complete web endpoint

[](#a-complete-web-endpoint)

Save as `public/index.php` and run `php -S localhost:8080 -t public`. It supports `?ip=`, `?format=json|plain` (default `plain`) and `?what=` for a single field:

```
GET /?ip=8.8.8.8                       → plain text
GET /?ip=8.8.8.8&format=json           → JSON
GET /?ip=8.8.8.8&what=country-iso-code → "US"

```

```
