В продолжение темы про IP, в этой статье будут рассмотрены способы определения страны, города и другой гео-ино о пользователе по его IP.
Наверное самая часто используемая библиотека для определения IP (оф. док на php.net). Оно и не мудрено, ведь бинарная БД + скомпилированное PHP расширение работают быстрее всех остальных способов.
Установка на Ubuntu Server:
Sudo apt-get install php5-geoip
После установки скачиваем последние обновления базы IP адресов:
После этих действий необходимо перезагрузить PHP. Это нужно для того что бы PHP интерпретатор подгрузил только что установленное расширение (php5-geoip) и новые базы IP адресов.
Также периодически необходимо обновлять базы 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 установлен, его можно использовать в коде, например так:
Этот способ, почти идентичен с 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 require geoip2/geoip2:~2.0
После этих двух несложных действий, можно начинать его использовать в своих PHP скриптах, пример:
country($_SERVER["REMOTE_ADDR"]); var_dump($geo->country->isoCode); var_dump($geo->country->name);
Также поставляется в виде 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" } }
Обратите внимание на следующие настройки:
Composer install
После установки самой библиотеки, обновится и БД IP адресов с офф. сайта.
Пример использования в PHP коде:
getCountry("89.163.220.14"));
Кроме использования composer пакета, также можно использовать REST API этого проекта, пример: http://api.sypexgeo.net/json/89.163.220.14 Об онлайн сервисах для определения гео инфы читайте ниже в этой статье.
Еще одна composer библиотека из-за рубежа.
Установка:
Composer require ip2location/ip2location-php
При установки этого composer пакета, и также при его обновлении, также будет обновляться БД IP адресов, которая находится по такому пути:
/vendor/ip2location/ip2location-php/databases/IP2LOCATION-LITE-DB1.BIN
Использование:
lookup("89.163.220.14", \IP2Location\Database::ALL); echo "
"; 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 "";
Появился сравнительно не давно, первая версия composer пакета была опубликована 27 сентября 2015.
Позиционирует себя как самый быстрый, по сравнению с такими конкурентами как: GeoIP и Sypex Geo. Но скорость достигается за счет малого размера базы, в следствии чего эта библиотека определяет только код страны.
Распространяется в виде composer пакета + бинарная БД в своем собственном формате.
Для установки этой библиотеки нужно всего лиш подключить composer пакет:
Composer require tabgeo/country
При этом установится как PHP библиотека так и сама БД:
Пример использования в PHP скрипте:
Стоит заметить, что TabGeo позволяет получить только двузначный код страны в формате ISO 3166-1 alpha-2 . Если вам нужно что то большее, например определить регион, город, временную зону, или пр., то нужно использовать например тот же GeoIP, т.к. он позволяет все это определить.
В качестве альтернативы можно использовать специальные онлайн сервисы. Принцип их работы прост: передаем GET параметром IP и в ответ получаем гео-инфу в формате JSON или XML.
Преимущество этого способы в том, что его можно использовать не только на стороне PHP, но и на стороне например JavaScript.
Но есть и существенные недостатки:
Вот несколько таких онлайн сервисов:
Почти все вышеперечисленные библиотеки предоставляют два вида баз данных IP адресов:
Более полная БД IP адресов с городами конечно будет работать немного медленнее в силу того что она больше по объему.
Наиболее правильно использовать GeoIP в виде PHP расширения. Т.к. работать он будет всегда и быстро. Также вы всегда можете обновить базы IP адресов.
Если нет возможности установить GeoIP в виде PHP расширения, то можно использовать один из composer пакетов: GeoIP, Sypex Geo, IP2LOCATION или TabGeo.
Если же использование composer пакета по какой-то причине не возможно, тогда остается использовать онлайн сервисы. Но обязательно нужно сделать кеширование запросов на эти сервисы в свою БД. Кеширование нужно для того что бы не отправлять один и тот же запрос по много раз. Достаточно один раз получить гео-инфу по интересующему ИП через онлайн сервис, после чего сохранить ее к себе в БД, и далее брать уже из БД. Таким образом вы уменьшите кол-во запросов на онлайн сервис и уменьшите вероятность того что онлайн сервис вас заблокирует за множественные запросы.
Стоит заметить, что почти у всех вышеперечисленных библиотек есть бесплатные и платные версии. В платных версиях вам будет доступно больше гео инфы чем в бесплатных.
Всем привет!
Не скажу, что часто, но время от времени у разработчиков появляется необходимость определения города по IP в PHP скрипте.
Например, вы решили облегчить работу пользователю по вводу контактной информации при оформлении заказа в Интернет магазине. Или хотите устанавливать язык интерфейса сайта в зависимости от страны, из которой к вам на сайт зашёл посетитель.
Ну, а чаще всего определение города по IP в PHP с помощью GeoIP, наверное, нужно разработчикам различных рекламных сетей, чтобы предлагать пользователям таргетированную рекламу в зависимости от географического местоположения.
Самому мне узнать страну по IP в PHP скрипте понадобилось всего один-единственный раз, когда я решил загружать на сайт виджеты различных соцсетей для пользователей из разных стран. Подробнее о том, зачем не это понадобилось и что в итоге получилось, я напишу в следующей статье.
А пока поговорим о том, сколько способов определения города и страны по IP в PHP существует и какие варианты их реализаций существуют.
Я специально так озаглавил описание первого способа. Дело в том, что в самом 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 есть два существенных минуса:
Ещё один способ узнать город по IP в PHP скрипте — это использование альтернативных серверных библиотек и баз информации для IP адресов, отличных от MaxMind.
Но они обладают теми же минусами, что и предыдущий вариант, т.к. являются всего лишь конкурентами MaxMind. Доступы к базам и возможность использования их API также платная. Бесплатно можно получить только список стран и городов по IP, в то время как при платном тарифе можно получать более широкий перечень данных.
Единственное преимущество над PHP GeoIP заключается в том, что данные библиотеки интегрируются в PHP коде, а не на уровне сервера, т.е. их можно использовать даже на shared хостингах.
Примером такой библиотеки является предоставляемая сервисом db-ip.com.
Кстати, указанный мною сервис предоставляет не только свою PHP библиотеку для получения гео данных по IP клиентов, но и доступ к базам информации по адресам. Так что, в принципе, никто вам не мешает использовать их в PHP GeoIP, чтобы использовать его API, но информацию брать из других источников.
Ну, и уж точно никто вам не мешает написать собственный парсер файлов баз IP адресов для получения из них информации самостоятельно, без всяких сторонних разрешений.
Ну, и вот я подошёл к финальному способу как узнать страну по IP в PHP и прочую гео информацию, который использовал сам на практике.
Он заключается в использовании API онлайн сервисов, которые позволяют получать данные по IP адресу в режиме онлайн.
Определять город по IP в PHP я решил именно данным способом, т.к. он лишён главного недостатка предыдущих. А именно, он самый простой в реализации — не нужно ничего устанавливать и настраивать на сервере, а, тем более, просить об этом техподдержку shared хостингов.
Для того, чтобы получить необходимую информацию по IP, достаточно всего лишь отправить запрос на определённый URL и обработать ответ.
Что касается стоимости их использования — в большинстве своём они так же платные, т.к. работают, как правило, на основе существующих коммерческих баз IP. Но есть и бесплатные сервисы, которые предоставляют, возможно, на такую полную информацию, как коммерческие, но зато её можно получать в неограниченном объёме.
Правда, они очень быстро прекращают своё существование, как ни странно, т.к. выжить предоставлением подобных услуг очень сложно. Это показал мой анализ бесплатных online сервисов определения городов и стран по IP, который я проводил в личных целях. Они мелькали на многих сайтах, но при попытке воспользоваться ими было понятно, что они прекратили своё существование.
В итоге, я отыскал то, что мне было необходимо, чем и хочу с вами определиться — http://www.geoplugin.com/
Данный сервис позволяет как определять город и другую информацию по IP на сайте сервиса, так и производить это из кода. Далее я приведу пример определения страны по IP в PHP скрипте с помощью geoplugin.com. коде осуществляется с помощью кода, описанного в статье по ссылке.
"", "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 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":"руб", "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 сервиса и имя необходимых параметров, которые вам нужно будет получить.
На этом у меня всё. Пишите ваши отзывы о статье в комментариях ниже и не забывайте делиться записью со своими друзьями в социальных сетях.
P.S. : если вам нужен сайт либо необходимо внести правки на существующий, но для этого нет времени и желания, могу предложить свои услуги.
Более 5 лет опыта профессиональной разработки сайтов. Работа с PHP , OpenCart , WordPress , Laravel , Yii , MySQL , PostgreSQL , JavaScript , React , Angular и другими технологиями web-разработки.
Опыт разработки проектов различного уровня: лендинги , корпоративные сайты , Интернет-магазины , CRM , порталы . В том числе поддержка и разработка HighLoad проектов . Присылайте ваши заявки на email [email protected] .
В которой упоминался мой «велосипед» отличающийся высокой скоростью работы. Одним из популярных вопросов стала возможность определения города по IP.
И вот несколько месяцев спустя, проект начинавшийся, как «for fun» перерос в самостоятельный проект.
Открыт отдельный сайт посвященный проекту Sypex Geo , на котором можно скачать свежие версии API и баз данных, а также ознакомиться с документацией.
Для желающих скорее протестировать правильность определения города по IP - вот ссылка на демо-страницу . А под хабракатом, я опишу некоторые технические подробности и приведу результаты небольшого тестирования.
При создании нового формата, ставились следующие приоритеты:
В БД хранится следующая информация:
В данный момент база основана на GeoLite City, но уже содержит полностью переработанное покрытие России, Украины и Беларуси. Постепенно будут уточняться другие страны, в первую очередь СНГ и Европа. База данных Sypex Geo City содержит названия городов и регионов на русском языке в UTF-8 (встречаются еще не переведенные названия), а также timezone.
Кроме того на сайте доступны другие базы данных преобразованные в формат SxGeo 2.1.
Результаты после 10 прогонов для каждого API в двух режимах (обычном и с кэшированием в памяти) усреднения и округления до десятков. Для каждого прогона создается массив из 50 000 случайных IP адресов, и в цикле осуществляется поиск каждым алгоритмом.
Предложение и пожелание приветствуются. Также ищутся желающие помочь с портированием API на другие языки, и созданием модулей для Apache и nginx.