Определение страны по IP-адресу через БД
Пару месяцев назад я писал статью о том, как узнать страну пользователя по его IP-адресу. И ещё в той статье я указал основные минусы подхода, который там использовался. Если вдруг, кто забыл или не смотрел, то напомню. Там мы узнавали страну через сторонний сервис. Однако, как Вы понимаете, здесь имеется два больших минуса: зависимость от работы стороннего сервера (может быть, он исчезнет или просто отключится), а также постоянное изменение алгоритма парсинга при изменении вёрстки стороннего сервиса. Как Вы понимаете, второй минус - очень существенен. Так как Вы никогда заранее не знаете, когда сломается Ваш скрипт. Вот по этим двум причинам очень часто страну пользователя определяют по IP-адресу через собственную базу данных. Вот об этом способе мы и поговорим в этой статье.
Не буду долго тянуть и сразу приступлю к подробному описанию того, что Вам необходимо сделать:
- Скачайте архив c файлом, содержащим SQL-запрос, по этой ссылке: скачать соответствия IP-адресов и стран.
- Зайдите в PHPMyAdmin.
- Создайте базу данных.
- Импортируйте SQL-файл в созданную базу данных. Обратите внимание: SQL-файл достаточно большой, поэтому вполне вероятно Вам придётся изменить файл настроек интерпритатора PHP. В частности, увеличить значения следующих переменных (они все должны быть больше размера SQL-файла): "memory_limit", "post_max_size", "upload_max_filesize".
Так как база достаточно большая (более 100 000 записей), то в SQL-файл я решил добавить индекс для двух полей. Это значительно увеличело производительность. Вам ничего уже делать не надо, но чтобы Вы понимали в будущем, что если вдруг с базой данных происходят большие тормоза, то подумайте о добавлении индекса на некоторые поля.
А теперь привожу PHP-код, который позволит узнать страну посетителя по его IP-адресу через базу данных:
<?php
$address = "localhost"; //Адрес базы данных
$user = "root"; //Имя пользователя базы данных
$password = ""; //Пароль пользователя
$name_db = "mydb"; //Имя базы данных
//Подключаемся к базе данных
$db = new mysqli($address, $user, $password, $name_db);
if (mysqli_connect_errno()) {
echo "Ошибка подключения";
exit();
}
$ip = "112.91.31.28"; //IP-адрес для проверки
//Преобразуем IP-адрес в нужный нам формат
$ip = sprintf("%u", ip2long($ip));
//Делаем выборку
$result_set = $db->query("SELECT `full_name` FROM `` WHERE ".$ip.">=`ip_from` AND ".$ip."<=`ip_to`");
//Получаем результат выборки
$row = $result_set->fetch_assoc();
//Выводим результат
echo "Страна - ".$row["full_name"];
?>
Здесь всё достаточно подробно прокомментировано, поэтому проблем с понимаем кода не должно возникнуть. Однако, хочется остановиться на описании двух функций:
- ip2long($ip) - функция, которая преобразует привычный нам IP-адрес (то есть с точками) в сетевой адрес.
- sprintf(string $format, mixed $string) - функция, которая преобразует заданную строку string к определённому формату format. Строка "format" состоит из ряда спецификаций конвертации. Не буду сейчас подробно это разбирать, так как на это потребуется отдельная статья, но в данном примере мы сообщаем, что наша строка - это десятиричное беззнаковое число целого типа (%u).
Если Вы всё сделали правильно, то подставляя в переменную ip какой-нибудь IP-адрес, Вы будете узнавать, какой стране он принадлежит. Всё бы было замечательно, однако, у этого способа также имеется один существенный недостаток: несмотря на большой размер таблицы, она не является полной, более того, совершенно неизвестно, что будет в будущем, и она может стать просто некорректной. И поэтому её надо время от времени обновлять. Обновлённые версии можно поискать в Интернете.
Теперь Вы знаете все доступные способы для того, чтобы узнать страну пользователя по IP-адресу. Каким способом пользоваться - решать только Вам, а свою задачу я выполнил.
-
- Михаил Русаков
Комментарии (3):
Заинтересовала конструкция "or die()". Почему-то только она не прекращает выполнения скрипта, и сообщения о последующих ошибках продолжают выводиться. Может, может дело в Денвере или каких-то настройках?
Ответить
Данная конструкция с new mysqli() не работает. Статью подправил. А вообще что die(), что exit() работают одинаково - то есть прекращают выполнение скрипта.
Ответить
У меня выдаёт ошибку Fatal error: Call to a member function fetch_assoc() on a non-object. Что делать?
Ответить
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.