О двух способах работы геолокации (GeoIP) в PHP

Мы начинаем потихоньку привыкать к Web 2.0 сайтам. Удобный (местами минималистический) дизайн, скруглённые уголки, тени, контент, генерируемый пользователем. А что главное с точки зрения юзабилити в w2.0-сайте? Не заставлять пользователя совершать лишние движения. Надо максимально облегчить ему процесс использования сайтом. Например, если в форме регистрации можно автоматически определить страну и город – зачем заставлять пользователя листать километровые списки?

В этой статье пойдёт речь о геолокации (определении местоположения пользователя) средствами PHP.

В нашей компании встала задача рефакторинга форм. Визуально они слишком перегружены, много лишних (но нужных) полей. Например, поля выбора страны и города. Список как стран, таки городов довольно внушителен, и пользователь тратит много времени, чтобы выбрать подходящий пункт. Это может оттолкнуть его от заполнения формы. Наша задача – определить его страну и город автоматически.

Задачу можно решить двумя способами: на уровне сервера приложений (PHP) и ну уровне веб-сервера (Nginx). Сам я рекомендую вам вариант с Nginx, а первый вы можете посмотреть в качестве альтернативы.

Геолокация на PHP

 

1. Качаем базу стран (в пакете geoip-database), городов, модуль для php и устанавливаем их в систему. Используется база MaxMind.

2. Проверяем, чтобы расширение php было подключено (/etc/php5/fpm/conf.d) и перезагружаем интерпретатор

3. Проверяем установку, запустив в броузере скриптик.

Узнать код страны можно с помощью этой команды:

Также есть много других интересных функций этого расширения.

  • geoip_continent_code_by_name — Получить двухбуквенный код континента
  • geoip_country_code_by_name — Получить двухбуквенный код страны
  • geoip_country_code3_by_name — Получить трехбуквенный код страны
  • geoip_country_name_by_name — Возаращает полное название страны
  • geoip_database_info — Получить версию БД GeoIP
  • geoip_db_avail — Проверить доступность БД GeoIP
  • geoip_db_filename — Возвращает имя файла БД GeoIP
  • geoip_db_get_all_info — Возвращает всю информацию о файлах БД в виде многомерного массива
  • geoip_id_by_name — Возвращает скоростную метрику интернет-канала пользователя (GEOIP_UNKNOWN_SPEED/GEOIP_DIALUP_SPEED/GEOIP_CABLEDSL_SPEED/GEOIP_CORPORATE_SPEED ).
  • geoip_isp_by_name — Возвращает имя провайдера (ISP) пользователя
  • geoip_org_by_name — Возвращает имя организации, за которой закреплен IP пользователя.
  • geoip_record_by_name — Возвращает информацию о местоположении пользователя (континент, страна, город, широта и долгота).
  • geoip_region_by_name — Возвращает код страны и региона
  • geoip_region_name_by_code — Возвращает название региона страны и код региона
  • geoip_time_zone_by_country_and_region — Возвращает часовой пояс клиента (по вычисленной стране и региону).

Геолокация в NGINX

 

Первый вариант геолокации весьма неплох. Это PECL расширение (geoip.so) поэтому, думается, оно работает довольно шустро. Однако может понадобиться вариант, когда нужно проводить маршрутизацию запросов веб-приложения в зависимости от местоположения (или языка) пользователя. Тут нам на помощь придёт модуль nginx HttpGeoIPModule. Устанока будет производиться на Nginx +php5_fpm (и у меня уже есть его конфиг).

1. Ставим базу GeoIP. Страны есть в deb-пакете, города качаем отдельно.

2. Добавляем в /etc/nginx/nginx.conf в секцию http строки:

2. В файл /etc/nginx/fastcgi_params добавляем переменные, котоыре будут прокидываться в массив $_SERVER веб-приложения:

Важно, чтобы инклюд этого файла “include /etc/nginx/fastcgi_params;” был указан в location секциях конфига вашего виртуального хоста Nginx.

3. Перезапускаем сервер, пишем простенький скрипт:

Варианты ответов:

  • ‘RU’ – всё работает. Ваша страна – Россия.
  • NULL – библиотека не подключена (смотрите конфиги)
  • string(”) – страну определить не удалось (бывает в случае, когда вы тестите на локальном компьютере, ведь в базе нет адреса 127.0.0.1 🙂

Теперь в массиве $_SERVER доступны данные геолокации с префиксом “GEOIP_”.

Обновление базы

База со странами (GeoIP.dat) обновляется вместе с пакетами, а базу городов (GeoLiteCity.dat) придётся обновлять вручную, ну или написать небольшой скрипт для автоматизации.

Литература

http://blo.in.ua/2009/09/22/php-geoip-extension/
http://wiki.nginx.org/HttpGeoIPModule
http://kbeezie.com/view/apache-mod_geoip-nginx/
http://www.maxmind.com/app/ip-location

12 Comments

    1. Дык ну точно так же:

      Install a port providing the database. For example in FreeBSD the port is called “GeoIP”.

      cd /usr/ports/net/GeoIP
      make install clean

      См. линку

    1. По идее примерно одинаково, но я бы предпочёл вариант с nginx.

  1. Идея конечно замечательная.
    Но к сожалению, некоторые IP не находит.
    Базу надо обновлять …
    А более произовтельный вариант это забор гео api, сохранение юзверю отметку что он и кто он, потом просто не юзать это…

  2. 2. Проверяем, чтобы расширение php было подключено (/etc/php5/fpm/conf.d) и перезагружаем интерпретатор

    Как проверяем?! ЧТо там должно быть? Как подключить, если не подключено?

    1. Создать файл /etc/php5/fpm/conf.d/geoip.ini со следующим содержанием:
      [geoip]
      extension=geoip.so
      Перезагрузить интерпретатор командой sudo service php5-fpm restart
      Открыть в браузере скрипт и проверить, чтобы там была секция geoip.
      Как-то так, Саша.

      1. Спасибо, уже сделал. Теперь проблема, что города все на английском, а нужны названия на русском.

  3. Библиотека nikolaevevgeGeoIp для Bitrix, Joomla, WordPress. Определяет регион посетителя сайта, город и страну. Не требует скачивания базы. Использует API для получения информации с дальнейшим кешированием “свежей” информации в базу данных.
    Скачать можно здесь http://blog.ivru.net/?id=82

  4. Бред вы пишите. Если юзеру надо зарегаться, то он это сделает, а вы только напрягаете код. На большинстве сайтов моя страна, а город никогда вообще не верно определяется и я сразу бегу от такого ужаса. Сайты сначала нормальные научитесь делать.

    1. О, вы откопали мою статью 11-летней давности 🙂 Зашел, прочитал, прослезился. Так вот, все равно не вижу проблемы. Там речь идет о предзаполнении форм, так что все норм. Некорректно определилось – выбираете что нужно, не нужна страна и город – ну так выпилите эти поля из формы просто.

Leave a Comment