PHP - Получаем гео-инфо пользователя по IP

В продолжение темы про IP, в этой статье будут рассмотрены способы определения страны, города и другой гео-ино о пользователе по его IP.

GeoIP в виде PHP расширения

Наверное самая часто используемая библиотека для определения IP (оф. док на php.net). Оно и не мудрено, ведь бинарная БД + скомпилированное PHP расширение работают быстрее всех остальных способов.

Установка на Ubuntu Server:

sudo apt-get install php5-geoip

После установки скачиваем последние обновления базы IP адресов:

sudo wget -N http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
sudo gunzip GeoIP.dat.gz
sudo mv GeoIP.dat /usr/share/GeoIP/

После этих действий необходимо перезагрузить PHP. Это нужно для того что бы PHP интерпретатор подгрузил только что установленное расширение (php5-geoip) и новые базы IP адресов.

sudo service php5-fpm restart # если вы используете NGINX
# или
sudo service apache2 restart # если вы используете Apache

Также периодически необходимо обновлять базы IP адресов:

sudo wget -N http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
sudo gunzip GeoIP.dat.gz
sudo mv GeoIP.dat /usr/share/GeoIP/

После обновления так же необходимо перезагружать PHP для применения обновленной базы IP адресов:

sudo service php5-fpm restart # если вы используете NGINX
# или
sudo service apache2 restart # если вы используете Apache

После того как GeoIP установлен, его можно использовать в коде, например так:

<?php
$countryCode = geoip_country_code_by_name($_SERVER['REMOTE_ADDR']);
echo $countryCode;

GeoIP в виде composer пакета

Этот способ, почти идентичен с GeoIP в виде расширения для PHP, за одним исключением: вам не нужно устанавливать на сервер дополнительные расширения.

Полезно это в том случае, если у вас нет root прав к серверу и вы не можете устанавливать PHP расширения.

Недостаток этого способа в том что он работает немного медленнее в сравнении со скомпилированным PHP расширением.

Подробную инструкцию можно почитать на офф. сайте, я лиш расскажу вкратце.

Первым делом необходимо скачать БД IP адресов в специальном формате (.mmdb) с офф. сайта, и поместить его в любую папку на сервере которая вам доступна:

wget -N http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz
gunzip GeoLite2-Country.mmdb.gz
mv GeoLite2-Country.mmdb /my-site/data/GeoIP/

Далее установить через composer офф. пакет geoip:

composer require geoip2/geoip2:~2.0

После этих двух несложных действий, можно начинать его использовать в своих PHP скриптах, пример:

<?php

require 'vendor/autoload.php';

use GeoIp2\Database\Reader;

$reader = new Reader('/my-site/data/GeoIP/GeoLite2-Country.mmdb');

$geo = $reader->country($_SERVER['REMOTE_ADDR']);
var_dump($geo->country->isoCode);
var_dump($geo->country->name);

Sypex Geo

Офф. сайт: https://sypexgeo.net/ru/

Также поставляется в виде PHP класса и бинарной библиотеки. К сожалению офф. composer пакета у нее нет. Но можно воспользоваться и не офф: https://packagist.org/packages/igi/sypexgeo.

Этот composer пакет хорош еще тем, что позволяет при выполнении команды "composer install" обновлять БД IP адресов.

Для того что бы установить этот composer пакет и настроить авто обновление БД IP адресов, нужно в файле composer.json прописать следующие настройки:

{
    "require-dev": {
        "igi/sypexgeo": "@dev"
    },
    "scripts": {
        "post-install-cmd": [
            "IgI\\SypexGeo\\Composer::installDatabases"
        ]
    },
    "extra": {
        "sypexgeo_remote": "https://sypexgeo.net/files/SxGeoCountry.zip",
        "sypexgeo_local": "/var/www/at0m1x.dev/test/data/SxGeo.dat"
    }
}

Обратите внимание на следующие настройки:

  • подключение пакета необходимо располагать в секции require-dev
  • при подключении пакета необходимо указывать уровень стабильности @dev
  • в секции sypexgeo_remote вместо SxGeoCountry.zip можно указать SxGeoCity_utf8.zip
  • в параметре sypexgeo_local вам необходимо указать свой путь к папке

Далее выполняем установку composer пакетов:

composer install

После установки самой библиотеки, обновится и БД IP адресов с офф. сайта.

Пример использования в PHP коде:

<?php

require 'vendor/autoload.php';

$sxGeo = new \IgI\SypexGeo\SxGeo(__DIR__ . '/data/SxGeo.dat');
var_dump($sxGeo->getCountry('89.163.220.14'));

Кроме использования composer пакета, также можно использовать REST API этого проекта, пример: http://api.sypexgeo.net/json/89.163.220.14 Об онлайн сервисах для определения гео инфы читайте ниже в этой статье.

IP2LOCATION

Офф. сайт: http://www.ip2location.com/

Еще одна composer библиотека из-за рубежа.

Установка:

composer require ip2location/ip2location-php

При установки этого composer пакета, и также при его обновлении, также будет обновляться БД IP адресов, которая находится по такому пути:

/vendor/ip2location/ip2location-php/databases/IP2LOCATION-LITE-DB1.BIN

Использование:

<?php

require 'vendor/autoload.php';

$db = new \IP2Location\Database(
    __DIR__ . '/vendor/ip2location/ip2location-php/databases/IP2LOCATION-LITE-DB1.BIN',
    \IP2Location\Database::FILE_IO
);

$records = $db->lookup('89.163.220.14', \IP2Location\Database::ALL);

echo '<pre>';
echo 'IP Number             : ' . $records['ipNumber'] . "\n";
echo 'IP Version            : ' . $records['ipVersion'] . "\n";
echo 'IP Address            : ' . $records['ipAddress'] . "\n";
echo 'Country Code          : ' . $records['countryCode'] . "\n";
echo 'Country Name          : ' . $records['countryName'] . "\n";
echo '</pre>';

TabGeo

Офф. сайт: http://tabgeo.com/ru/index/

Появился сравнительно не давно, первая версия composer пакета была опубликована 27 сентября 2015.

Позиционирует себя как самый быстрый, по сравнению с такими конкурентами как: GeoIP и Sypex Geo. Но скорость достигается за счет малого размера базы, в следствии чего эта библиотека определяет только код страны.

Распространяется в виде composer пакета + бинарная БД в своем собственном формате.

Для установки этой библиотеки нужно всего лиш подключить composer пакет:

composer require tabgeo/country

При этом установится как PHP библиотека так и сама БД:

PHP - получаем гео-инфо пользователя по IP

Пример использования в PHP скрипте:

<?php

require 'vendor/autoload.php';

$country = TabGeo\country('89.163.220.14');
var_dump($country);

Стоит заметить, что TabGeo позволяет получить только двузначный код страны в формате ISO 3166-1 alpha-2. Если вам нужно что то большее, например определить регион, город, временную зону, или пр., то нужно использовать например тот же GeoIP, т.к. он позволяет все это определить.

Онлайн сервисы для гео-таргетинга

В качестве альтернативы можно использовать специальные онлайн сервисы. Принцип их работы прост: передаем GET параметром IP и в ответ получаем гео-инфу в формате JSON или XML.

Преимущество этого способы в том, что его можно использовать не только на стороне PHP, но и на стороне например JavaScript.

Но есть и существенные недостатки:

  • работает это не так быстро как PHP библиотека;
  • вы не можете обновить БД IP адресов;
  • ваш сервер могут заблокировать за частые обращения.

Вот несколько таких онлайн сервисов:

Заключение

Почти все вышеперечисленные библиотеки предоставляют два вида баз данных IP адресов:

  • облегченный, только со списком стран, как правило в названии содержит Country;
  • более полный, в котором кроме стран также содержится инфо о крупных городах, как правило в названии содержит City и больше весит;

Более полная БД IP адресов с городами конечно будет работать немного медленнее в силу того что она больше по объему.

Наиболее правильно использовать GeoIP в виде PHP расширения. Т.к. работать он будет всегда и быстро. Также вы всегда можете обновить базы IP адресов.

Если нет возможности установить GeoIP в виде PHP расширения, то можно использовать один из composer пакетов: GeoIP, Sypex Geo, IP2LOCATION или TabGeo.

Если же использование composer пакета по какой-то причине не возможно, тогда остается использовать онлайн сервисы. Но обязательно нужно сделать кеширование запросов на эти сервисы в свою БД. Кеширование нужно для того что бы не отправлять один и тот же запрос по много раз. Достаточно один раз получить гео-инфу по интересующему ИП через онлайн сервис, после чего сохранить ее к себе в БД, и далее брать уже из БД. Таким образом вы уменьшите кол-во запросов на онлайн сервис и уменьшите вероятность того что онлайн сервис вас заблокирует за множественные запросы.

Стоит заметить, что почти у всех вышеперечисленных библиотек есть бесплатные и платные версии. В платных версиях вам будет доступно больше гео инфы чем в бесплатных.