Как определить город, страну и регион по IP-адресу посетителя с помощью бесплатной базы данных GeoLite в Symfony 3

Хотя многие разработчики утверждают, что геолокация должна выполняться через браузер, во многих ситуациях вы не можете использовать API геолокации браузера. Это, независимо от ваших причин, может быть решено путем получения наиболее важной информации об IP-адресе пользователя, таких как его страна, город и язык. Однако откуда и как вы можете получить такую ​​информацию только с IP? Существует много сторонних сервисов, некоторые из которых платные, которые позволяют получать такую ​​информацию с помощью REST API. Вы отправляете IP-адрес пользователя в качестве аргумента и извлекаете информацию о нем. Тем не менее, существует важный фактор, который мешает многим разработчикам использовать такие API, наиболее важным из которых является то, что каждый раз, когда пользователь посещает веб-сайт, в API REST будет выполняться запрос для получения геоинформации. Для здравомыслящего ума это обычно неоправданный подход.

Вот почему есть другие варианты, например, основанные на базах данных. Одна из наиболее известных бесплатных альтернатив этого подхода — база данных GeoLite2 от MaxMind. В этой статье мы покажем вам, как получить страну, город и локаль из IP-адреса посетителя, используя базу данных GeoLite2 в вашем проекте Symfony.

Преимущества этого подхода перед использованием остальных API

Самая разумная причина, по которой у вас будет локальная база геоданных на вашем сервере, заключается в том, что вам не нужно выполнять запрос к любому стороннему серверу. Вместо этого вы запрашиваете локальную базу данных, где производительность зависит только от вашего сервера, а не от соединения или доступности сторонних сервисов. У вас есть база данных рядом с вами для запроса информации о IP-адресе пользователя, ситуация не может быть более ясной.

1. Скачать бесплатные базы данных GeoLite2

В качестве первого шага вам понадобится двоичная база данных GeoLite в вашем проекте или доступная на системном уровне. Вы можете скачать базу с официального MaxMind GeoLite2 можно бесплатно здесь:

База данных GeoLite

В этом уроке мы будем использовать и включать базу данных в наш собственный проект в /private каталог нашего проекта Symfony (обратите внимание, что этот каталог не существует и, следовательно, должен быть создан, вы можете изменить путь к базе данных в соответствии с вашими потребностями), и мы будем использовать версию базы данных City, которая позволяет нам получить информация, которую мы упомянули в этой статье, в частности, город, страна и локаль IP-адреса посетителя. Базы данных сжимаются с помощью tar, поэтому вы сможете извлечь его содержимое из командной строки, используя следующую команду:

tar -xzf GeoLite2-City_20180206.tar.gz

В качестве альтернативы в других операционных системах, таких как Windows, вы можете просто извлечь его содержимое, используя 7Zip, Winrar или другой инструмент для распаковки. Теперь, когда у вас есть база данных в вашем проекте, структура каталогов должна выглядеть следующим образом:

Заметка

Если есть несколько проектов, которые используют базу данных, вы можете разместить базу данных в другом месте, где все проекты могут иметь к ней доступ. Так как в этом уроке нам нужна только база данных в этом проекте, мы также размещаем ее внутри проекта.

Структура проекта GeoLite2 Symfony

GeoLite2-City.mmdb Размер файла составляет около 63 МБ, и он содержит всю информацию, необходимую для получения необходимой информации по IP-адресу пользователя.

2. Установите MaxMind GeoIP2 PHP API

Чтобы прочитать базу данных, вам не нужно будет размещаться в MySQL или другом менеджере баз данных. База данных имеет специальный формат от создателей GeoIP, а именно MaxMind DB. Формат файла MaxMind DB — это формат базы данных, который отображает адреса IPv4 и IPv6 в записи данных с использованием эффективного дерева двоичного поиска. Бинарная база данных разделена на три части:

  1. Двоичное дерево поиска. Каждый уровень дерева соответствует одному биту в 128-битном представлении адреса IPv6.
  2. Раздел данных. Это значения, возвращаемые клиенту для определенного IP-адреса, например, «США», «Нью-Йорк» или более сложный тип карты, состоящий из нескольких полей.
  3. Метаданные базы данных. Информация о самой базе данных.

Для получения дополнительной информации о типе базы данных, используемой этим проектом, пожалуйста, прочитайте больше о MaxMind DB здесь.

Теперь нам нужен парсер для этого формата базы данных. К счастью, команда MaxMind написала потрясающую библиотеку для PHP, которая делает взаимодействие с базой данных довольно простым, и вы сможете получить геоинформацию об IP-адресе пользователя с помощью всего лишь нескольких строк кода. Мы говорим о MaxMind GeoIP PHP Api, пакете, который предоставляет API для веб-сервисов и баз данных GeoIP2. API также работает с бесплатными базами данных GeoLite2 (той, которую мы используем). Вы можете установить этот пакет в свой проект Symfony с помощью composer, выполнив следующую команду:

composer require geoip2/geoip2

Для получения дополнительной информации об этой библиотеке, пожалуйста, посетите официальный репозиторий на Github здесь. После установки пакета вы сможете использовать его классы на ваших контроллерах Symfony.

3. Получение Geo-информации о IP-адресе пользователя с контроллера.

Теперь, когда у вас есть база данных и оболочка для чтения информации из нее, вы можете просто перейти к запросу информации из базы данных об указанном IP. Логика для достижения этой цели заключается в следующем: объявить переменную, которая содержит абсолютный (локальный) путь к базе данных GeoLite2-City. Это необходимо указать в качестве первого аргумента в новом экземпляре класса Reader GeoIp2, который вы будете использовать для запроса информации об IP. Наконец, выполните метод city из созданного экземпляра, предоставив IP-адрес, с которого вы хотите получить информацию в качестве первого аргумента. Очевидно, что вам нужно предоставить действительный IP-адрес, иначе читатель сгенерирует исключение, очевидно, вам также необходимо быть готовым к тому, что IP-адрес пользователя может не распознаваться базой данных, поэтому вам нужно поймать AddressNotFoundException когда вы запрашиваете информацию о IP:

get('kernel')->getRootDir() . '/../private/geolite2-city/GeoLite2-City.mmdb';
// Create an instance of the Reader of GeoIp2 and provide as first argument
// the path to the database file
$reader = new Reader($GeoLiteDatabasePath);
try{
// if you are in the production environment you can retrieve the
// user's IP with $request->getClientIp()
// Note that in a development environment 127.0.0.1 will
// throw the AddressNotFoundException
// In this example, use a fixed IP address in Minnesota
$record = $reader->city('128.101.101.101');
} catch (AddressNotFoundException $ex) {
// Couldn't retrieve geo information from the given IP
return new Response("It wasn't possible to retrieve information about the providen IP");
}
return new JsonResponse($record);
}
}

В нашем примере с указанным IP вы получите JSON-ответ следующего вывода в браузере:

{
"city": {
"geoname_id": 5037649,
"names": {
"de": "Minneapolis",
"en": "Minneapolis",
"es": "Mineápolis",
"fr": "Minneapolis",
"ja": "ミネアポリス",
"pt-BR": "Minneapolis",
"ru": "Миннеаполис",
"zh-CN": "明尼阿波利斯"
}
},
"continent": {
"code": "NA",
"geoname_id": 6255149,
"names": {
"de": "Nordamerika",
"en": "North America",
"es": "Norteamérica",
"fr": "Amérique du Nord",
"ja": "北アメリカ",
"pt-BR": "América do Norte",
"ru": "Северная Америка",
"zh-CN": "北美洲"
}
},
"country": {
"geoname_id": 6252001,
"iso_code": "US",
"names": {
"de": "USA",
"en": "United States",
"es": "Estados Unidos",
"fr": "États-Unis",
"ja": "アメリカ合衆国",
"pt-BR": "Estados Unidos",
"ru": "США",
"zh-CN": "美国"
}
},
"location": {
"accuracy_radius": 5,
"latitude": 44.9759,
"longitude": -93.2166,
"metro_code": 613,
"time_zone": "America/Chicago"
},
"postal": {
"code": "55414"
},
"registered_country": {
"geoname_id": 6252001,
"iso_code": "US",
"names": {
"de": "USA",
"en": "United States",
"es": "Estados Unidos",
"fr": "États-Unis",
"ja": "アメリカ合衆国",
"pt-BR": "Estados Unidos",
"ru": "США",
"zh-CN": "美国"
}
},
"subdivisions": [
{
"geoname_id": 5037779,
"iso_code": "MN",
"names": {
"en": "Minnesota",
"es": "Minnesota",
"fr": "Minnesota",
"ja": "ミネソタ州",
"pt-BR": "Minesota",
"ru": "Миннесота",
"zh-CN": "明尼苏达州"
}
}
],
"traits": {
"ip_address": "128.101.101.101"
}
}

Обратите внимание, что $record Переменная является объектом stdClass, поэтому здесь нет методов получения. Вы можете получить свойства объекта в PHP следующим образом:

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

MaxMind не предоставляет официальной поддержки для бесплатных баз данных GeoLite2. Если у вас есть вопросы о базах данных GeoLite2 или API GeoIP2, см. GeoIP вопросы и ответы от stackoverflow.

Ссылка на основную публикацию
Adblock
detector