О двух способах работы геолокации (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