Bundle for use maxmind/GeoIP2 in Symfony.
Pretty simple with Composer, run:
composer req gpslab/geoip2
To configure auto-update the database you need to generate your personal licence key.
- Sign up for a MaxMind account (no purchase required)
- Login and generate a licence key
- Save your licence key
- Open download page 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'
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;license_key
- your personal licence key.
You can change this URL, for example, if you want to use a proxy to download the database. You can customize the source URL in the configuration.
gpslab_geoip:
license: 'XXXXXXXXXXXXXXXX'
edition: 'GeoLite2-City'
url: 'https://example.com/GeoLite2-City.tar.gz'
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. 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'
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' ]
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 library.
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
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));
}
}
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
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
This bundle is under the MIT license. See the complete license in the file: LICENSE