Используем базу IP по городам GeoLite City от MaxMind. Зона покрытия этой базы описана здесь. Лицензия проста как кактус: пользуйтесь на здоровье, даже в коммерческих целях, но все рекламные материалы и документация к продукту должны содержать фразу: «This product includes GeoLite data created by MaxMind, available from http://maxmind.com/». Ну и как обычно — никаких гарантий. От платной версии free-базу отличает чуть-чуть худшее покрытие. Но нам это не мешает.
Данная библиотека существует в виде PECL-расширения, которое не идет в стандартном наборе с PHP. Если модуль у вас на сервере установлен, пользуйтесь им, если нет — используйте библиотеку отдельно. Кстати, API базы есть для разных языков.
В репозитории PEAR находится библиотека для доступа к файлу базы. А сам файл базы необходимо скачать с сервера и ежемесячно обновлять. Скачали базу, скачали API. Распаковали базу (файл GeoLiteCity.dat и каталог GeoIP). Каталог GeoIP нужно положить в каталог Net (последний создать), или изменить строку 663 строку в файле GeoIP.php.
База готова к эксплуатации. Посмотрите, как работает пример отпределения IP посетителя сайта по базе. Вот код примера (index.php):
<?php print "Search Started<br \>\r\n"; require('GeoIP.php'); $geoip = Net_GeoIP::getInstance('GeoLiteCity.dat', Net_GeoIP::STANDARD); $data = $geoip->lookupLocation( isset($_SERVER['HTTP_REMOTE_ADDR']) ? $_SERVER['HTTP_REMOTE_ADDR'] : $_SERVER['REMOTE_ADDR'] //nginx? ); if ( is_null($data) ) print "Region wasn't found!<br \>\r\n"; else print "Found! You are from {$data->city}, {$data->countryName}<br \>\r\n"; print "© 2008, <a href=\"https://valera.ws/\">feedbee</a><br />\r\n"; print "This product includes GeoLite data created by MaxMind, available from <a href=\"http://www.maxmind.com/\">http://www.maxmind.com/</a>."; ?>
Обратите внимание, что если не найден IP в базе, будет возвращен NULL. Но вомзможен случай, когда не будет найден только город, а страна найдется. В этом случае $data->city вернет NULL.