PHPackages                             gpslab/geoip2 - 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. gpslab/geoip2

ActiveSymfony-bundle[Utility &amp; Helpers](/categories/utility)

gpslab/geoip2
=============

A Symfony Bundle for the Maxmind GeoIP2 API

v2.1.3(1y ago)531.5M↓42.5%13[5 issues](https://github.com/gpslab/geoip2/issues)3MITPHPPHP &gt;=7.2.0CI failing

Since Jan 24Pushed 1w ago5 watchersCompare

[ Source](https://github.com/gpslab/geoip2)[ Packagist](https://packagist.org/packages/gpslab/geoip2)[ Docs](https://github.com/gpslab/geoip2)[ RSS](/packages/gpslab-geoip2/feed)WikiDiscussions master Synced 2w ago

READMEChangelog (10)Dependencies (10)Versions (31)Used By (3)

[![Latest Stable Version](https://camo.githubusercontent.com/23c919267c06819ee0dfe51fabd5a01f097517a040e1f12552a6e08e708f0124/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6770736c61622f67656f6970322e7376673f6d61784167653d33363030266c6162656c3d737461626c65)](https://packagist.org/packages/gpslab/geoip2)[![Test](https://github.com/gpslab/geoip2/actions/workflows/test.yaml/badge.svg)](https://github.com/gpslab/geoip2/actions/workflows/test.yaml)[![Coverage Status](https://camo.githubusercontent.com/73174f94f59e0928a26ed91361baf5fd20ba6c3dffbd589614c444db3346ac67/68747470733a2f2f696d672e736869656c64732e696f2f636f766572616c6c732f6770736c61622f67656f6970322e7376673f6d61784167653d33363030)](https://coveralls.io/github/gpslab/geoip2?branch=master)[![License](https://camo.githubusercontent.com/c1b304d23c406f9824c0b3eb2ff68f9d152bc40eb22195ae0d4e39b28de88a46/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6770736c61622f67656f6970322e7376673f6d61784167653d33363030)](https://github.com/gpslab/geoip2)

A Symfony Bundle for the Maxmind GeoIP2 API
===========================================

[](#a-symfony-bundle-for-the-maxmind-geoip2-api)

Bundle for use [maxmind/GeoIP2](https://github.com/maxmind/GeoIP2-php) in Symfony.

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

[](#installation)

Pretty simple with [Composer](http://packagist.org), run:

```
composer req gpslab/geoip2
```

Configuration
-------------

[](#configuration)

To configure auto-update the database you need to generate your personal licence key.

#### Steps for generate licence key

[](#steps-for-generate-licence-key)

1. [Sign up for a MaxMind account](https://www.maxmind.com/en/geolite2/signup) (no purchase required)
2. Login and generate a [licence key](https://www.maxmind.com/en/accounts/current/license-key)
3. Save your licence key
4. Open [download page](https://www.maxmind.com/en/download_files) and find your needed DB edition `ID` and copy value from first column.

Example configuration:

```
gpslab_geoip:
    # Your personal licence key
    license: 'XXXXXXXXXXXXXXXX'

    # One of database edition IDs:
    #   GeoLite2-ASN
    #   GeoLite2-City
    #   GeoLite2-Country
    #   GeoIP2-City
    #   GeoIP2-Country
    #   GeoIP2-Anonymous-IP
    #   GeoIP2-Domain
    #   GeoIP2-ISP
    edition: 'GeoLite2-City'
```

#### Database source URL

[](#database-source-url)

By default, this URL is used to download a new databases `https://download.maxmind.com/app/geoip_download?edition_id={edition_id}&license_key={license_key}&suffix=tar.gz`

- `edition_id` - character ID name from first column on [download page](https://www.maxmind.com/en/download_files);
- `license_key` - your personal [licence key](https://www.maxmind.com/en/accounts/current/license-key).

You can change this URL, for example, if you download the database from a mirror of your own. You can customize the source URL in the configuration.

```
gpslab_geoip:
    license: 'XXXXXXXXXXXXXXXX'
    edition: 'GeoLite2-City'
    url: 'https://example.com/GeoLite2-City.tar.gz'
```

#### Proxy

[](#proxy)

If the outgoing connections of your server go through a proxy, declare the proxy server itself. Do not put it in the source URL, the URL is the address of the database and not of the proxy.

```
gpslab_geoip:
    license: 'XXXXXXXXXXXXXXXX'
    edition: 'GeoLite2-City'
    proxy: 'http://proxy.example.com:3128'
```

The proxy is used for downloading the databases of all configured editions. Credentials can be a part of the address, they are sent in the `Proxy-Authorization` header.

```
gpslab_geoip:
    license: 'XXXXXXXXXXXXXXXX'
    edition: 'GeoLite2-City'
    proxy: 'http://user:password@proxy.example.com:3128'
```

Url encode a login or a password that contains special characters. Keeping the credentials in a parameter is a better idea than keeping them in the configuration file.

```
gpslab_geoip:
    license: '%env(MAXMIND_LICENSE)%'
    edition: 'GeoLite2-City'
    proxy: '%env(HTTPS_PROXY)%'
```

The `http`, `https`, `socks4`, `socks4a`, `socks5` and `socks5h` schemes are supported. Use `http` for a plain proxy and `https` for a proxy that expects a TLS connection to itself. A proxy of any scheme can download a database over HTTPS.

A database is downloaded with the [cURL](https://www.php.net/manual/en/book.curl.php) extension when it is installed and with PHP streams otherwise. Install the extension if you need a SOCKS proxy, a proxy that authenticates with anything other than Basic, or if the `allow_url_fopen` option is disabled on your server. PHP streams support HTTP proxies only and a SOCKS proxy is rejected with an explicit error.

### Target download path

[](#target-download-path)

By default, new databases downloaded in `%kernel.cache_dir%/{edition_id}.mmdb`, where `edition_id` is a character ID name from first column on [download page](https://www.maxmind.com/en/download_files). That is, by default, the new database will be downloaded into folder `var/cache/{env}/`. Keeping the database in the cache folder for each environment may not be optimal. You can choose a common directory for all environments.

```
gpslab_geoip:
    license: 'XXXXXXXXXXXXXXXX'
    edition: 'GeoLite2-City'
    path: '%kernel.project_dir%/var/GeoLite2-City.mmdb'
```

#### Permissions

[](#permissions)

By default, a downloaded database gets the `0755` permissions. A database is a data file and does not need to be executable, so you may prefer to make it less permissive. The permissions are applied to the databases of all configured editions.

```
gpslab_geoip:
    license: 'XXXXXXXXXXXXXXXX'
    edition: 'GeoLite2-City'
    permissions: '0644'
```

Quote the value: the YAML parser does not treat `0644` as an octal number, it returns the `'0644'` string. Both notations are accepted, as well as the YAML `0o644` and the decimal `420`. The directory of the database is still created with the `0755` permissions, it has to stay traversable.

#### Localization

[](#localization)

By default, the English locale is used for GeoIP record. You can change the locale for record and declare multiple locales for fallback.

```
gpslab_geoip:
    license: 'XXXXXXXXXXXXXXXX'
    edition: 'GeoLite2-City'
    locales: [ 'ru', 'en' ]
```

Usage
-----

[](#usage)

You can get GeoIP2 reader service:

```
use GeoIp2\Database\Reader;

// get a GeoIP2 reader
$reader = $this->get(Reader::class);
// or
//$reader = $this->get('geoip2.reader');

// get a GeoIP2 City model
$record = $reader->city('128.101.101.101');

print($record->country->isoCode . "\n"); // 'US'
print($record->country->name . "\n"); // 'United States'
print($record->country->names['zh-CN'] . "\n"); // '美国'

print($record->mostSpecificSubdivision->name . "\n"); // 'Minnesota'
print($record->mostSpecificSubdivision->isoCode . "\n"); // 'MN'

print($record->city->name . "\n"); // 'Minneapolis'

print($record->postal->code . "\n"); // '55455'

print($record->location->latitude . "\n"); // 44.9733
print($record->location->longitude . "\n"); // -93.2323
```

For more example see the [GeoIP2](https://github.com/maxmind/GeoIP2-php) library.

Multiple databases
------------------

[](#multiple-databases)

You can use multiple GeoIP databases in one application. Need update configuration file.

```
gpslab_geoip:
    databases:
        default:
            license: 'XXXXXXXXXXXXXXXX'
            edition: 'GeoLite2-City'
        country:
            license: 'XXXXXXXXXXXXXXXX'
            edition: 'GeoLite2-Country'
        asn:
            license: 'XXXXXXXXXXXXXXXX'
            edition: 'GeoLite2-ASN'
```

Using in application:

```
// get a GeoIP2 reader for City database
$default_reader = $this->get('geoip2.database.default_reader');
// or
//$default_reader = $this->get(Reader::class);
// or
//$default_reader = $this->get('geoip2.reader');

// get a GeoIP2 reader for Country database
$country_reader = $this->get('geoip2.database.country_reader');

// get a GeoIP2 reader for ASN database
$asn_reader = $this->get('geoip2.database.asn_reader');
```

You can rename the default database.

```
gpslab_geoip:
    default_database: 'city'
    databases:
        asn:
            license: 'XXXXXXXXXXXXXXXX'
            edition: 'GeoLite2-ASN'
        city:
            license: 'XXXXXXXXXXXXXXXX'
            edition: 'GeoLite2-City'
        country:
            license: 'XXXXXXXXXXXXXXXX'
            edition: 'GeoLite2-Country'
```

```
// get a GeoIP2 reader for City database
$default_reader = $this->get('geoip2.database.city_reader');
// or
//$default_reader = $this->get(Reader::class);
// or
//$default_reader = $this->get('geoip2.reader');
```

In order not to repeat the license key and locales for each database, you can specify them once.

```
gpslab_geoip:
    license: 'XXXXXXXXXXXXXXXX' # global license
    locales: [ 'ru', 'en' ] # global locales
    default_database: 'city'
    databases:
        asn:
            edition: 'GeoLite2-ASN'
            locales: [ 'fr' ] # customize locales
        city:
            edition: 'GeoLite2-City'
            url: 'https://example.com/GeoLite2-City.tar.gz' # customize url
            path: '%kernel.project_dir%/var/GeoLite2-City.mmdb' # customize path
        country:
            edition: 'GeoLite2-Country'
            license: 'YYYYYYYYYYYYYYYY' # customize license
```

### GeoIP data in client locale

[](#geoip-data-in-client-locale)

If you want to show the GeoIP data to the user and show them in the user locale, then you can use the reader factory.

```
use GpsLab\Bundle\GeoIP2Bundle\Reader\ReaderFactory;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class GeoIPController
{
    public function index(Request $request, ReaderFactory $factory): Response
    {
        $client_locale = $request->getLocale();
        $client_ip = $request->getClientIp();
        $database_name = 'default';
        $fallback_locale = 'en';

        $reader = $factory->create($database_name, [$client_locale, $fallback_locale]);
        $record = $reader->city($client_ip);

        return new Response(sprintf('You are from %s?', $record->country->name));
    }
}
```

Console commands
----------------

[](#console-commands)

### Update GeoIP database

[](#update-geoip-database)

Execute console command for update all databases:

```
php bin/console geoip2:update

```

If you use multiple databases, then for config:

```
gpslab_geoip:
    # ...
    databases:
        asn:
            # ...
        city:
            # ...
        country:
            # ...
```

You can update several databases:

```
php bin/console geoip2:update city country

```

Optionally installing splitbrain/php-archive uses significantly less memory when updating a database and can avoid out of memory errors:

```
composer req splitbrain/php-archive

```

### Download GeoIP database

[](#download-geoip-database)

You can download custom database with console command:

```
php bin/console geoip2:download https://example.com/GeoLite2-City.tar.gz /path/to/GeoLite2-City.mmdb

```

License
-------

[](#license)

This bundle is under the [MIT license](http://opensource.org/licenses/MIT). See the complete license in the file: LICENSE

###  Health Score

58

—

FairBetter than 98% of packages

Maintenance69

Regular maintenance activity

Popularity53

Moderate usage in the ecosystem

Community26

Small or concentrated contributor base

Maturity69

Established project with proven stability

 Bus Factor1

Top contributor holds 91.7% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~100 days

Total

30

Last Release

570d ago

Major Versions

1.2.x-dev → v2.0.02020-02-04

PHP version history (3 changes)v1.0.0PHP &gt;=5.4.0

v2.0.0PHP &gt;=7.1.0

v2.1.0PHP &gt;=7.2.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/9a6415c83577efe7b70d9ae4a3bb12958adc11c16e530ff844ff217b0fd0c54a?d=identicon)[Peter Gribanov](/maintainers/Peter%20Gribanov)

---

Top Contributors

[![peter-gribanov](https://avatars.githubusercontent.com/u/1954436?v=4)](https://github.com/peter-gribanov "peter-gribanov (299 commits)")[![Lustmored](https://avatars.githubusercontent.com/u/2358046?v=4)](https://github.com/Lustmored "Lustmored (11 commits)")[![mreiden](https://avatars.githubusercontent.com/u/6321246?v=4)](https://github.com/mreiden "mreiden (5 commits)")[![antedebaas](https://avatars.githubusercontent.com/u/5467398?v=4)](https://github.com/antedebaas "antedebaas (3 commits)")[![Bukashk0zzz](https://avatars.githubusercontent.com/u/1908342?v=4)](https://github.com/Bukashk0zzz "Bukashk0zzz (3 commits)")[![Huluti](https://avatars.githubusercontent.com/u/5782198?v=4)](https://github.com/Huluti "Huluti (1 commits)")[![ChrisKinnan](https://avatars.githubusercontent.com/u/53341594?v=4)](https://github.com/ChrisKinnan "ChrisKinnan (1 commits)")[![classaxe](https://avatars.githubusercontent.com/u/9293057?v=4)](https://github.com/classaxe "classaxe (1 commits)")[![aalwash](https://avatars.githubusercontent.com/u/3220347?v=4)](https://github.com/aalwash "aalwash (1 commits)")[![jaimenj](https://avatars.githubusercontent.com/u/6050201?v=4)](https://github.com/jaimenj "jaimenj (1 commits)")

---

Tags

geoipmaxmindmaxmind-geoip2-apiphpsymfony-bundlesymfony-flex

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/gpslab-geoip2/health.svg)

```
[![Health](https://phpackages.com/badges/gpslab-geoip2/health.svg)](https://phpackages.com/packages/gpslab-geoip2)
```

###  Alternatives

[chameleon-system/chameleon-base

The Chameleon System core.

1029.4k6](/packages/chameleon-system-chameleon-base)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
