Импорт базы Ipgeobase в локальную базу данных и дальнейшее использование.

Частенько сервер ipgeobase.ru не справляется с нагрузками. Если Вы напрямую к нему обращаетесь, то во время зависаний ipgeobase могут возникать трудности в работе вашего сайта, а может и не совсем корректная его работа из за использования гео привязки пользователей. Поэтому будет целесообразно скачать базу на свой сервер, импортировать его в базу данных и уже локально использовать. При такой работе перебоев в работе сайта связанных с недоступностью ipgeobase не будет. Сейчас опишу как импортировать  данные ipgeobase  в базу данных mysql и как их использовать.

Вам нужно скачать этот архив: geo.zip — тут находится php файл, который будет импортировать текстовую базу с ipgeobase в mysql. Для работы скрипта нужно будет настроить подключение к базе данных (указать сервер, пользователя и пароль).

Также в архиве находится sh файл, который после предварительного изменения можно поставить как задание на крон. И вызывать с определенной периодичностью (например, раз в неделю), чтобы поддерживать базу данных в актуальном состоянии.

Если Вы не умеете настраивать крон, то для Вас подробная инструкция как все сделать вручную.

[1] Скачиваем и распаковываем файл geo.zip в папку на сервере

[2] В архиве есть файл geo.sql импортируем его в вашу БД. Этот файл создаст две пустые таблицы с названиями geo__base и geo__cities
Содержание файла geo.sql



[3] В php файлах import_geobase.php и check_geobase.php в начале каждого файла указываем параметры подключения к вашей БД

[4] Отсюда http://ipgeobase.ru/cgi-bin/Archive.cgi скачиваем архив geo_files.zip (http://ipgeobase.ru/files/db/Main/geo_files.zip)

[5] Распаковываем этот архив. Среди извлеченных файлов будут файлы с названием cidr_optim.txt и cities.txt — эти файлы нужно загрузить на сервер рядом с php файлами из архива geo.zip

[6] В браузере запускаем файл import_geobase.php — Ждем окончания импорта. Проверяем недавно созданные таблицы. После запуска импорта они очищаются и в них заносятся данные.
Содержание файла import_geobase.php



[7] Если шестой пункт прошел успешно, в браузере открываем файл check_geobase.php
Содержание файла check_geobase.php



[8] В итоге после всего этого должны увидеть нечто вроде этого:

Array
(
[long_ip1] => 1560264704
[long_ip2] => 1560272895
[ip1] => 92.255.192.0
[ip2] => 92.255.223.255
[country] => RU
[city_id] => 1283
[city] => Казань
[region] => Республика Татарстан
[district] => Приволжский федеральный округ
[lat] => 55.7965
[lng] => 49.1082
)
Название города: Казань

Если у Вас это получилось. Поздравляю 🙂 Если нет, попробуй внимательно пройтись по всем пунктам несколько раз и найти свою ошибку. Эти скрипты я даю лишь как примеры, а не готовые решения. Бесплатным обучением PHP и благотворительностью не занимаюсь. Написанный тут материал передаю как есть. Поэтому в комментариях желательно писать только с конкретными вопросами именно по работе скрипта. Буду благодарен, если источником информации при обсуждении похожих тем на разных форумах будете давать ссылку на этот пост.


На правах рекламы:

Солнечные жаркие дни не за горами. Успейте купить солнечные очки. Какие очки купить и обзоры солнечных очков Вам представит сайт sunglasses-reviews.ru


Если Вам интересны темы, про которые я пишу в своем блоге, то Вы можете Подписаться на обновления. Подписываться на новости и обновления можно по емайл или через популярные сервисы yandex и google!

Эта запись была опубликована в рубрике PHP кусочки. Добавить в закладки ссылку.

52 в ответ на Импорт базы Ipgeobase в локальную базу данных и дальнейшее использование.:

  1. Ольга пишет:

    Большое спасибо! Именно то, что очень хотелось найти =) Отлично работает!

  2. Евгений пишет:

    А сколько в среднем вес базы?

    • FaNiska пишет:

      В Mysql около 11 Mb. Размер запакованного архива с базой смотрите на сайте ipgeobase.ru в разделе «архив»

  3. Surgery пишет:

    Скрипт работает, но что-то с кодировкой. Если нужна кодировка cp1251, то что нужно сделать? Достаточно будет ли в файле import_geobase.php заменить set charset utf8 и т.д. на charset cp1251?

  4. FaNiska пишет:

    Чтобы это сделать, нужно поменять кодировку базы данных и в скрипте убрать строки, которая из windows-1251 конвертирует в utf-8

    $row = iconv(‘windows-1251’, ‘utf-8’, $row); // вот это

  5. Михаил пишет:

    Привет!
    В первую очередь спасибо за скрипт. Сейчас реализую у себя на сайте все работает.
    Только у меня была проблема $long_ip получалось отрицательным, нашел решение дописал строку в check_geobase.php после:
    $long_ip = ip2long($ip);
    добавил:
    if ($long_ip < 0) $long_ip += pow(2,32);

  6. Алекс пишет:

    Спасибо за скрипт! Очень помогло

  7. arktur пишет:

    php -f index.php 77.108.109.99
    \PHP Notice: Undefined variable: ipa in on line 120
    PHP Warning: Invalid argument supplied for foreach() in on line 120
    PHP Notice: Undefined variable: ipa in on line 120
    PHP Warning: Invalid argument supplied for foreach() in on line 120
    Передайте функции IP
    почему то не работает, я что то не так делаю?

    • FaNiska пишет:

      Да. Откройте php файл и посмотрите. Скрипт не предназначен для запуска в консоли. IP адрес скрипт получает из глобальных переменных $_SERVER, а Ваш вариант передачи ip не предусмотрен.

  8. Класс!
    Все работает отлично.
    Спасибо большое!

  9. Алексей пишет:

    Здравствуйте.

    Скрипт отличный. Спасибо большое.
    Единственное возник вопрос. В файле geo.php идет обращение к:
    $link = ‘ipgeobase.ru:7020/geo?ip=’.$this->ip;

    Т.е. обращение все равно к этому сайту а не к базе, в которую мы залили данные?

    • FaNiska пишет:

      Обратите внимание на содержание файла check_geobase.php
      Там показан пример как обращаться к базе данных и получать локальные данные для ip адреса.

      • Алексей пишет:

        Т.е. вот из этого архива что выше, файл geo.php еще не готов для работы с локальной базой?

        check_geobase.php — также обращается к geo.php

        • FaNiska пишет:

          check_geobase.php обращается к geo.php не для запроса с геобазы, а лишь для того чтобы узнать IP адрес. Советую получше изучить скрипт.

          • Vadim пишет:

            А зачем обращаться к серверу ipgeobase.ru, если можно IP узнать через функцию:
            $_SERVER[‘REMOTE_ADDR’]
            У меня на денвере работает, если только вписать туда IP:
            $link = ‘ipgeobase.ru:7020/geo?ip=46.151.240.15’
            Пробывал в базе исправить один московский IP на 2130706433 (127.0.0.1 — локальный IP денвера), город не определился. Выходит, что локальную базу не читает.

          • FaNiska пишет:

            Скрипт не обращается к серверу чтобы узнать IP. Скрипт обращается к серверу чтобы узнать гео-данные об этом IP. Внимательней посмотрите код.

          • Vadim пишет:

            Скрипт обращается к серверу чтобы узнать гео-данные об этом IP ?
            А зачем же тогда скачивать базу на свой сервер?
            Если-бы я хорошо разбирался в кодах, то я бы сам написал этот скрипт.
            Описание об установке и работе не совсем понятно.
            Импорт отлично работает, сразу разобрался. Спасибо!
            «index.php» вобще не понятно для чего, там даже данных для подключения к базе нет.
            А «check_geobase.php» работает, даже если строку обращения к «ipgeobase.ru» в «geo.php» удалить. И еще много чего удалял в «geo.php», при этом работает.
            Увы для моего проекта этот скрипт не подходит. А за базу и импорт базы большое спасибо!

          • FaNiska пишет:

            Класс в файле geo.php нужен для работы без импорта базы. Если Вы решили воспользоваться импортом базы, то, как Вы заметили, необходимости обращаться к стороннему серверу нет и данные нужно извлекать лишь с базы данных.

          • Vadim пишет:

            Ну что, тогда пора новую статью написать о том как использовать свою локальную базу? Чтобы там можно было выбрать вывод любых данных из базы и вывод информации в зависимости от города или региона посетителя.

          • FaNiska пишет:

            В седьмом пункте этой статьи уже указано как пользоваться локальной базой.
            Можете вместо переменной $ip вводить любой IP полученный любым удобным Вам способом.
            Однако хочу предупредить что $_SERVER[‘REMOTE_ADDR’] не поможет выявить реальный IP если посетитель вашего сайта использует прокси или пользуется функцией «турбо» в Опере или яндекс.браузере.

          • Vadim пишет:

            А вот сейчас только понял, что «geo.php» не нужен. И мои посетители с прокси меня не интересуют.

  10. nuklon пишет:

    все сделал по рецепту, определяю ip = 176.120.198.15, перевожу в число = 1334262257. Но такое число в диапазоне итальянских ip почему-то.
    Когда обращаюсь через ваш класс к вашей БД, то определяет все нормально.
    из-за чего такое может быть?

  11. nuklon пишет:

    все проблема решена, спасибо пользователю Михаилу

  12. Yodo пишет:

    Спасибо, все настроил, все работает!)

  13. kamil пишет:

    а это в джумла 2.5 работает и как установить поподробней пожалуйста))))

    • FaNiska пишет:

      Заработает если сумеете поставить. Никаких подробностей не расскажу, не рассматриваю частные примеры использования.

  14. kamil пишет:

    и как понять импортируем в бд(базу данных) надо её закинуть в мененджер файлов

    • FaNiska пишет:

      Думаю уровень ваших знаний пока маловат, чтобы с этими скриптами возиться. Почитайте в интернете что из себя представляет импорт, и как нужно импортировать дамп базы данных.

  15. silver пишет:

    Советую вам убрать индекс из таблицы geo__base. У меня на компьютере время запроса на выборку одной строки из таблицы с индексом составляет 0,17с. Без индекса: 0,017. Быстрее в 10 раз.

    • FaNiska пишет:

      Так то индекс предназначен для того, чтобы ускорять. Не стоит делать выводы из-за единичного случая. При моих тестах с индексом было гораздо быстрее, чем без него

  16. Skitalec пишет:

    Здравствуйте!

    Скрипт отличный. Только вот при импорте в бд выдается ошибка:

    Incorrect integer value: ‘- ‘ for column ‘city_id’ at row 1

    Если подумать, то ничего удивительного в этом нет. city_id имеет тип INT, т.е. целочисленное значение и «-» туда никак не подходит.

    Подскажите, пожалуйста, как быть?

    • FaNiska пишет:

      Попробуйте поменять тип поля в БД или регулярное выражение в скрипте. Когда я делал, такой ошибки не ловил, возможно были незначительные изменения.

  17. prgrant пишет:

    Отличный скрипт! Пробовал версию без базы данных — сайт частенько подвисал из-за постоянного обращения к ipgeobase. Советую всем настроить данную версию вместе с crontab’ом!

  18. Иван пишет:

    Для адреса 8.8.8.8 функция get_data возвращает значение null. Ошибка заключается в неверном слиянии массивов $res1 и $res2
    Ниже исправленная версия:

    function get_data($ip)
    {
    $country = ‘N/A’;
    if(empty($ip))
    exit(‘Передайте функции IP’);
    $long_ip = ip2long($ip);
    if ($long_ip < 0) $long_ip += pow(2,32);
    $q = mysql_query("SELECT * FROM geo__base WHERE long_ip1=’$long_ip’ LIMIT 1″);
    $data = false;
    if (mysql_num_rows($q))
    {
    $res1 = mysql_fetch_assoc($q);
    $q = mysql_query(«SELECT * FROM geo__cities WHERE city_id=’$res1[city_id]’ LIMIT 1″);
    if (mysql_num_rows($q))
    {
    $res2 = mysql_fetch_assoc($q);
    //$data = array_merge($res1, $res2); <- ТУТ ОШИБКА
    }
    $data = array_merge((array)$res1, (array)$res2);
    }
    return $data;
    }

    • FaNiska пишет:

      В Вашем примере есть ошибка, так как переменной res2 может не быть и функция array_merge вернет false — тоже самое, что получится и в моем варианте кода. Только у меня вариант ошибки предусмотрен и заключен в условие, а у Вас нет.

  19. Сергей пишет:

    Уважаемый автор!
    Большое спасибо за скрипт. Работает отлично. Я выбрал вариант с переносом данных в свою SQL базу, но есть проблема. При сохранении IP более 127.127.127.127 функция ip2long присваивает целочисленной переменной отрицательное значение (это потому, что переменная signed а не unsigned). И, соответственно, город не определяется.
    При сохранении результата ip2long в check_geobase.php в строке 47 необходимо сделать замену:
    вместо $long_ip = ip2long($ip);
    необходимо написать $long_ip=sprintf(‘%u’, ip2long($ip));
    В данном случае всё работает хорошо.

    Ещё раз спасибо за отличный скрипт.
    С уважением,
    Сергей

  20. Алексей пишет:

    регулярные выражения учил по одной книге, но вот ваш патерн понять не могу, могли бы разъяснить что он проверяет?

    • FaNiska пишет:

      Смотря про какой паттер Вы говорите. Если парсинг данных со строки, то паттерн служит для того, чтобы достать из строки данные так, чтобы их можно было внести в БД.

  21. Евгений пишет:

    А почему импорт не сделать через массовое добавление (смотрим в поисковике bulk import mysql)? Например по 100 записей за проход — время импорта в 100 раз снизится почти.

    • FaNiska пишет:

      Представленное мною решение — это всего лишь один вариант из ста. Каждый может на его основе сделать улучшенный способ импорта. Мое решение не претендует быть лучшим, я лишь привел пример и не заморачивался 🙂 Если разбираетесь, улучшайте и используйте как считаете нужным.

  22. ЛЕО пишет:

    Не стал переносить на сайт, решил попробовать вариант вызова Вашей БД с вашего сайта: $link = ‘http://www.ipgeobase.ru:7020/geo?ip=’.’62.220.33.216′;
    На Денвере все работает, как только переношу на сайт — тишина! Какая может быть причина? Подскажите, плиз.

    • FaNiska пишет:

      Возможно на хостинге не включен curl. Причин может быть несколько, но для начала проверьте именно наличие curl’а.

  23. ЛЕО пишет:

    В дополнение к вышенаписанному:
    $ch = curl_init($link);
    echo «init: «.$ch.»;
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $string = curl_exec($ch);
    curl_close($ch);
    echo «string: «.$string.»;

    На Денвере все это работает, на сайте — висит!
    Ничего не выводится… 🙁

  24. ЛЕО пишет:

    Функция phpinfo(); на моем бесплатном хостинге не работает!
    Может посоветуете нормальный, где Ваша тема заработает? Спасибо, заранее…

  25. ЛЕО пишет:

    Проверил. На хостинге curl включен!

  26. ЛЕО пишет:

    На Денвере получилось!
    Но, не все. Вывелось содержимое массива в другой кодировке:
    _____________________________________________
    echo »;
    print_r($data);
    echo »;

    // если нужно использовать только 1 значение из массива, то можно выводить так
    echo ‘Название города: ‘.$data[‘city’].»;
    ____________________________________________

    Результат:

    Array
    (
    [long_ip1] => 1054613504
    [long_ip2] => 1054617599
    [ip1] => 62.220.32.0
    [ip2] => 62.220.47.255
    [country] => RU
    [city_id] => 1956
    [city] => Нижний Новгород
    [region] => Нижегородская область
    [district] => Приволжский федеральный округ
    [lat] => 56.3299
    [lng] => 44.0092
    )
    Название города: Нижний РќРѕРІРіРѕСЂРѕРґ

    ______________________________

    Как поменять кодировку вывода?

    • FaNiska пишет:

      Как использовать другую кодировку для БД и в скрипте написано в комментариях скрипта, да и можно легко догадаться как поменять кодировку, если просто открыть скрипт. Но у Вас похоже, что можно обойтись сменой кодировки через htaccess. Поищите в интернете как поменять кодировку через .htaccess — я просто не знаю к какой кодировке вы пытаетесь получить данные.

  27. Максим пишет:

    Сделал на основе вашего класса и локальной базы георедирект на российскую и украинскую версии сайта. Крым и Россия идут на рублевый поддомен, остальная Украина идет на гривнёвый поддомен. Все остальные идут на страницу ручного выбора версии сайта. horeca-service.com
    Пришлось делать потому как не только валюта разная, но и ассортимент товаров в зависимости от стран поставщиков. Компания теперь международная.
    Спасибо за класс и метод.

  28. Роман пишет:

    На IPv6 не работает к сожелению

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *