Определение города по IP в PHP: 3 способа

Автор: | 07.11.2017

opredelenie-goroda-po-ip-v-phpВсем привет!

Не скажу, что часто, но время от времени у разработчиков появляется необходимость определения города по IP в PHP скрипте.

Например, вы решили облегчить работу пользователю по вводу контактной информации при оформлении заказа в Интернет магазине. Или хотите устанавливать язык интерфейса сайта в зависимости от страны, из которой к вам на сайт зашёл посетитель.

Ну, а чаще всего определение города по IP в PHP с помощью GeoIP, наверное, нужно разработчикам различных рекламных сетей, чтобы предлагать пользователям таргетированную рекламу в зависимости от географического местоположения.

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

А пока поговорим о том, сколько способов определения города и страны по IP в PHP существует и какие варианты их реализаций существуют.

PHP GeoIP — стандартный функционал стороннего производства

Я специально так озаглавил описание первого способа. Дело в том, что в самом PHP определить город и страну по IP адресу нельзя — язык не обладает для этого необходимыми инструментами.
Зато в официальной документации есть подсказка, как это сделать.

PHP GeoIP — это сторонняя библиотека, которую необходимо подключать дополнительно, несмотря на то, что описание функций, входящих в неё, является частью официальной документации PHP — http://php.net/manual/ru/ref.geoip.php

В принципе, мотивы разработчиков PHP вполне понятны.

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

Во-вторых, GeoIP PHP работает на базе перечня IP адресов, соответствующих определённым странам и городам. Поэтому GeoIP PHP требует постоянной поддержки и расширения/модернизации существующей базы, что являлось бы лишней головной болью разработчиков PHP.

Ну, и в-третьих, определение города по IP в PHP — возможность достаточно редко используемая на практике.

В итоге, из-за этих факторов PHP GeoIP является сторонним расширением, поддержкой которого и созданием API для интеграции на существующих сайтах занимается компания MaxMind, ссылка на которую присутствует в описании данной библиотеки.

Я не буду заниматься описанием процесса её установки на сервер, т.к. я сам на практике этим не занимался, и в Интернете на данный момент полно мануалов по установке PHP GeoIP как на Linux, так и на Windows сервера.

Могу только сказать, что у данного способа определения города, страны и прочей гео информации по IP в PHP есть два существенных минуса:

  1. Доступ к базе полной информации по IP адресам, предоставляемой компанией MaxMind, платный. Причём, сумма в долларах, как ни странно :-) Бесплатно доступны лишь существенно урезанные варианты — http://dev.maxmind.com/geoip/geoip2/geolite2/
  2. Учитывая, что PHP GeoIP — стороннее расширение, его необходимо будет отдельно устанавливать на сервер, что при условии использования shared хостинга может стать затруднительным мероприятием. Можно конечно, обратиться в техподдержку, но не факт, что вам помогут. Мне, например, при просьбе установить Sphinx отказали.

Определение города по IP в PHP с помощью альтернативных библиотек

Ещё один способ узнать город по IP в PHP скрипте — это использование альтернативных серверных библиотек и баз информации для IP адресов, отличных от MaxMind.

Но они обладают теми же минусами, что и предыдущий вариант, т.к. являются всего лишь конкурентами MaxMind. Доступы к базам и возможность использования их API также платная. Бесплатно можно получить только список стран и городов по IP, в то время как при платном тарифе можно получать более широкий перечень данных.

Единственное преимущество над PHP GeoIP заключается в том, что данные библиотеки интегрируются в PHP коде, а не на уровне сервера, т.е. их можно использовать даже на shared хостингах.

Примером такой библиотеки является предоставляемая сервисом db-ip.com.

Есть ещё и другие, конечно, но я не занимался их целенаправленным поиском. Если вы знаете ещё какие-то, то можете поделиться ними в комментариях.

Кстати, указанный мною сервис предоставляет не только свою PHP библиотеку для получения гео данных по IP клиентов, но и доступ к базам информации по адресам. Так что, в принципе, никто вам не мешает использовать их в PHP GeoIP, чтобы использовать его API, но информацию брать из других источников.

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

Как определить город по IP в PHP online

Ну, и вот я подошёл к финальному способу как узнать страну по IP в PHP и прочую гео информацию, который использовал сам на практике.

Он заключается в использовании API онлайн сервисов, которые позволяют получать данные по IP адресу в режиме онлайн.

Определять город по IP в PHP я решил именно данным способом, т.к. он лишён главного недостатка предыдущих. А именно, он самый простой в реализации — не нужно ничего устанавливать и настраивать на сервере, а, тем более, просить об этом техподдержку shared хостингов.

Для того, чтобы получить необходимую информацию по IP, достаточно всего лишь отправить запрос на определённый URL и обработать ответ.

Что касается стоимости их использования — в большинстве своём они так же платные, т.к. работают, как правило, на основе существующих коммерческих баз IP. Но есть и бесплатные сервисы, которые предоставляют, возможно, на такую полную информацию, как коммерческие, но зато её можно получать в неограниченном объёме.

Правда, они очень быстро прекращают своё существование, как ни странно, т.к. выжить предоставлением подобных услуг очень сложно. Это показал мой анализ бесплатных online сервисов определения городов и стран по IP, который я проводил в личных целях. Они мелькали на многих сайтах, но при попытке воспользоваться ими было понятно, что они прекратили своё существование.

В итоге, я отыскал то, что мне было необходимо, чем и хочу с вами определиться — http://www.geoplugin.com/

Данный сервис позволяет как определять город и другую информацию по IP на сайте сервиса, так и производить это из кода. Далее я приведу пример определения страны по IP в PHP скрипте с помощью geoplugin.com. Определение IP в PHP коде осуществляется с помощью кода, описанного в статье по ссылке.

<?php

$client  = @$_SERVER['HTTP_CLIENT_IP'];
$forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
$remote  = @$_SERVER['REMOTE_ADDR'];
$result  = array('country'=>'', 'city'=>'');

if(filter_var($client, FILTER_VALIDATE_IP)) $ip = $client;
elseif(filter_var($forward, FILTER_VALIDATE_IP)) $ip = $forward;
else $ip = $remote;

$ip_data = @json_decode(file_get_contents("http://www.geoplugin.net/json.gp?ip=".$ip));    
if($ip_data && $ip_data->geoplugin_countryName != null)
{
    $result = $ip_data->geoplugin_countryCode;
}

echo $result;

?>

Как видите, суть приведённого кода заключается в определении IP адреса клиента, причём учитывается возможность его подключения через прокси, и отправке запроса по API GeoPlugin с дальнейшим декодированием и анализом результатов.

В моём примере, как я уже и говорил, результатом работы данного скрипта будет являться код страны клиента сайта. Вообще, полный список возвращаемых параметров выглядит так (для примера решил взять IP Новосибирской области РФ):

{
  "geoplugin_request":"195.208.128.3",
  "geoplugin_status":200,
  "geoplugin_credit":"Some of the returned data includes GeoLite data created by MaxMind, available from <a href='http:\/\/www.maxmind.com'>http:\/\/www.maxmind.com<\/a>.",
  "geoplugin_city":"Novosibirsk",
  "geoplugin_region":"Novosibirsk",
  "geoplugin_areaCode":"0",
  "geoplugin_dmaCode":"0",
  "geoplugin_countryCode":"RU",
  "geoplugin_countryName":"Russian Federation",
  "geoplugin_continentCode":"EU",
  "geoplugin_latitude":"55.09",
  "geoplugin_longitude":"82.6519",
  "geoplugin_regionCode":"53",
  "geoplugin_regionName":"Novosibirsk",
  "geoplugin_currencyCode":"RUB",
  "geoplugin_currencySymbol":"&#1088;&#1091;&#1073;",
  "geoplugin_currencySymbol_UTF8":"\u0440\u0443\u0431",
  "geoplugin_currencyConverter":58.9289
}

Как видите, данный сервис использует упоминаемый ранее MaxMind (параметр geoplugin_credit), но платную информацию или нет — сложно предположить. С одной стороны, ссылка на источник говорит о том, что используется бесплатный доступ к БД IP, но, с другой, мы видим не только страну и город, но и ещё много всякой информации, включая город, географические координаты координаты (langitude, latitude), текущую валюту и даже её курс.

Так что данный сервис можно назвать PHP GeoIP онлайн. Единственное его отличие от серверного аналога — то, что он получает информацию по IP немного медленнее за счёт отсутствия серверного кэширования. Но это ещё не значит, что его нет на самом сервере GeoPlugin 😉 Так что недостаток этот, скорее, символический.

В любом случае, разработчики GeoPlugin заслуживают на аплодисменты, а, в особенности, ещё и за то, что они даже не захламили своё сайт контекстной рекламой. Т.е. как они вообще выживают — непонятно. Единственный способ сказать им «спасибо» — это пожертвования на PayPal счёт.

Кстати, приведённый мною PHP код для определения города по IP является универсальным. Можете его использовать для получения гео данных и с помощью других сервисов. Единственное, что вам нужно будет в нём изменить — это URL API сервиса и имя необходимых параметров, которые вам нужно будет получить.

На этом у меня всё. Пишите ваши отзывы о статье в комментариях ниже и не забывайте делиться записью со своими друзьями в социальных сетях.

Если у вас есть какие-то замечания или вы хотите поделиться другими способами определения города по IP в PHP, то оставляйте их также в комментариях.

Пока :-)

  1. 5
  2. 4
  3. 3
  4. 2
  5. 1
7 голосов, в среднем: 4.4 из 5

2 комментария к статье "Определение города по IP в PHP: 3 способа"

  1. Алешка

    А как забацать имена городов по русски? Или где найти список всех городов из этой базы на английском, что бы потом сопоставлять через foreach если добавить в массив, или switch case(ом), и потом выводить по русски?

    1. Pashaster Автор

      День добрый :-) Для Вашего кейса есть целых три способа решения:

      • Подробно изучать API сервиса и искать соответствующие методы.
      • Скачать базу городов себе на сервер с других источников и при каждой операции определения города по IP делать поиск по этому файлу.
      • Воспользоваться библиотеками транслитерации и переводить латинские названия городов на русский на лету. Если будет интересно, как это сделать, могу написать статью. Останется только подправить правила транслита под свои нужды.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *