Иногда для сайта нужно определить из какой страны и/или города текущий посетитель. Есть различные интернет-сервисы, которые предоставляют такую информацию по API или другими способами. Но надежнее и быстрее будет использовать специальное php-расширение GeoIP. Так же существует аналогичное отдельное расширения для его установки с помощью Composer, я рассмотрю оба варианта.

Страница данного php-расширения на http://php.net.
Его использование имеет главное преимущество по сравнению с различными API – скорость. Так же вы не зависите от доступности внешнего сервиса. Небольшой минус это то, что базу данных расширения (в виде отдельного файла) желательно периодически обновлять, особенно если нужна информация не только по странам но и по городам. Правда это можно автоматизировать с помощью cron.


Установка в качестве php-расширения на Windows.


Для скачивания расширения переходим по ссылке http://pecl.php.net/package/geoip, выбираем последнюю версию и после перехода по соответствующей ссылке скачиваем архив для своей конфигурации php.
Я скачивал тут:
http://pecl.php.net/package/geoip/1.1.1/windows

Подробнее про установку расширения: http://fi2.php.net/manual/ru/install.pecl.windows.php

После копирования архива расширения, сохраняем файл php_geoip.dll в папку ext с интерпретатором php. Например у меня это E:\OpenServer 5.2.7\modules\php\PHP-7.1\ext

Далее нужно включить расширение в конфигурационном файле php.ini, т.е. прописать
extension=php_geoip.dll

Узнать, где находится используемый сервером php.ini, можно посмотрев результат выполнения функции
phpinfo();
т.е. вы можете просто прописать эту строку в php файл и выполнить. Результат:


После активации расширения сохраните php.ini, перезагрузите веб-сервер и снова проверьте phpinfo(), в нем должен появиться отдельный раздел с новым расширением.

В OpenServer текущий конфигурационный файл php.ini открывается так:


Прописываем строку подключающую данное расширение в конце списка расширений. После активации расширения сохраните php.ini, перезагрузите веб-сервер и снова проверьте phpinfo(), в нем должен появиться отдельный раздел с новым расширением:




Если при перезагрузке сервера у вас выскочит ошибка:

значит вы скачали неверную версию расширения.

Если сейчас попробовать задействовать расширение geoip:
$country = geoip_country_code_by_name('www.example.com');
if ($country) {
    echo 'Хост расположен в: ' . $country;
}
получим ошибку такого плана:
Warning: geoip_country_code_by_name(): Required database not available at W:/modules/http/Apache-PHP-7/bin/GeoIP.dat. in …

Дело в том, что данные для работы расширения, а именно соответствие хостов или IP с названиями стран и городов хранится не в самом файле php_geoip.dll, а в отдельном файле с данными. О чем и свидетельствует эта ошибка. Согласно ее, файл GeoIP.dat должен находиться в папке W:/modules/http/Apache-PHP-7/bin (у вас может быть другой путь).
Поэтому переходим по ссылке http://dev.maxmind.com/geoip/legacy/geolite
Качаем архив в строке
GeoLite Country (Binary / gzip)
и файл из архива GeoIP.dat переносим в W:/modules/http/Apache-PHP-7/bin (согласно ошибке).

После этого, определение страны согласно хоста 'www.example.com' должно выдать:
Хост расположен в: US
Конечно можно вместо хоста указывать IP адрес.


При переносе проекта использующего php-расширение GeoIP на хостинг проверьте доступно ли оно там. У меня расширения указываются при выборе версии php в cPanel:


Если нет - придется устанавливать его в качестве пакета для Composer (об этом ниже).

При установке расширения на хостинге так же необходимо будет скопировать файл с базой данных. У меня это:
/usr/share/GeoIP/GeoIP.dat
Путь подскажет сообщение об ошибке) Проверьте есть ли у вас доступ на сохранение в эту папку.


На странице расширения http://php.net/manual/ru/book.geoip.php можно посмотреть какие у него есть функции. Например выведем полное название страны:
$country = geoip_country_name_by_name('www.example.com');
echo $country; //United States

Для использования некоторых функций потребуется дополнительная установка баз данных. Название нужного файла вы увидите в тексте ошибки. Например файл с данными по городам можно скачать там же где и базу по странам: https://dev.maxmind.com/geoip/legacy/geolite

Базы данных обновляются в первый вторник каждого месяца.



Установка GeoIP в виде Composer пакета.


Если хостинг не поддерживает расширение GeoIP, есть возможность установить его версию - пакет для Composer. Это так же позволит использовать кое-какие дополнительные функции.

Установка:
composer require geoip2/geoip2:~2.0

После установки необходимо скачать файл с данными в формате (.mmdb) по ссылке http://dev.maxmind.com/geoip/geoip2/geolite2
Отдельно файлы с базами данных по городам и по странам.

Пример использования:
use GeoIp2\Database\Reader;

//Страна
$readerCountry = new Reader('geoIP/GeoLite2-Country.mmdb');
$geo = $readerCountry->country('195.69.222.18');
var_dump($geo->country->isoCode); //UA
var_dump($geo->country->name); //Ukraine

//Город
$readerSity = new Reader('geoIP/GeoLite2-City.mmdb');
$geo = $readerSity->city('195.69.222.18');
var_dump($geo->city->name); //Zhytomyr

В качестве аргумента, конструктору класса Reader нужно передать путь к файлу с данными. Согласно примера, я создал общедоступную папку geoIP куда перенес файлы.

При этом можно получить название на русском языке:
$geo->country->names['ru'] 
Подробнее про установку расширения с помощью и еще примеры смотрите на https://github.com.

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