Определение местоположения пользователя по IP и создание счетчика посещений

от автора

Здравствуйте уважаемые Хабравчане! Создав свой сайт, я добавил на него счетчик посещений с какого-то сервиса (что-то типа qoo…) он работал с JS. и частенько обновлялся. И я не мог посмотреть сколько в действительности было посетителей на сайте. Так же я хотел знать с каких IP адресов ко мне заходят, а так же к какой стране этот IP относится. Что бы не создавать велосипед решил погулять на форумах. нашел много разной информации в том числе и про SxGeo. Мне понравился данный вариант так как там можно сразу узнать и страну и город. Так как я только начинаю изучать PHP и таких людей наверно много я решил выложить данную статью. Только не кусочек кода отвечающий за определение страны и города, а полностью рабочий код. Итак, начнем.

Для начала необходимо создать таблицу в БД куда будут заноситься данные о посетителях. У меня все поля кроме id, идут с типом varchar 255 и сравнением utf8_general_ci, для id тип int 10 атрибут UNSIGNED и конечно же A/I. Теперь создадим конфигурационный файл в котором запишем параметры подключения к нашей БД. И наконец скачиваем SxGeo.php и SxGeoCity.dat с сайта sypexgeo.net ссылки на оба файла: раз и два.

В SxGeo.php на 55 строке при обращении к библиотеке необходимо заменить название файла с SxGeo.dat на SxGeoCity.dat. Все, подготовительные работы окончены.

Создаем файл stats.php (название файла на ваш выбор) и в нем устанавливаем соединение с нашей БД:

<?php include_once ('config.php'); include_once ('SxGeo.php');  $mysqli = new mysqli($server, $user, $pswd, $db); if ($mysqli->connect_errno) { printf("Не удалось подключиться: %s\n", $mysqli->connect_error); exit();} $mysqli -> select_db($db) or die ("Невозможно открыть $db"); if (!$mysqli->set_charset("utf8")) {     printf("Ошибка при загрузке набора символов utf8: %s\n", $mysqli->error);     exit();}

Теперь через функцию getRealIpAddr() получаем ip-клиента:

public function getRealIpAddr() {     if (!empty($_SERVER['HTTP_CLIENT_IP']))        // Определяем IP     { $ip=$_SERVER['HTTP_CLIENT_IP']; }     elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))     { $ip=$_SERVER['HTTP_X_FORWARDED_FOR']; }     else { $ip=$_SERVER['REMOTE_ADDR']; }     return $ip;}

Следом проверяем, не бот ли к нам зашел в гости:

if (strstr($_SERVER['HTTP_USER_AGENT'], 'YandexBot')) {$visitor='YandexBot';} //Выявляем поисковых ботов elseif (strstr($_SERVER['HTTP_USER_AGENT'], 'Googlebot')) {$visitor='Googlebot';} else { $visitor=$_SERVER['HTTP_USER_AGENT']; }

и передаем в $ip значение функции getRealIpAddr().

$ip = getRealIpAddr();

Теперь создаем объект SxGeo и определяем город, страну и регион:

$SxGeo = new SxGeo('SxGeoCity.dat', SXGEO_BATCH | SXGEO_MEMORY); $result = $SxGeo->getCityFull($ip); 

Можете воспользоваться функцией var_export(), чтобы посмотреть, какой массив данных он вам вернет, может Вам понадобиться что-то еще, кроме того, что я предлагаю. Идем дальше. Выбираем из этого массива значения страны, региона и города. И для освобождения места удаляем объект SxGeo.

$city = $result["city"]["name_ru"]; $region = $result["region"]["name_ru"]; $country = $result["country"]["name_ru"]; unset($SxGeo);

Теперь определяем дату, время и страницу сайта, на которую заходили.

$date = date("H:i:s d.m.Y");        // определяем дату и время события $host = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];    // определяем страницу сайта

Экранируем специальные символы в строке для использования в SQL выражении и заносим наши данные в таблицу.

$ip   = $mysqli->real_escape_string($ip); $date = $mysqli->real_escape_string($date); $host  = $mysqli->real_escape_string($host); $region = $mysqli->real_escape_string($region); $country = $mysqli->real_escape_string($country); $city = $mysqli->real_escape_string($city); $visitor = $mysqli->real_escape_string($visitor); if ($query = $mysqli -> query("INSERT INTO `pre_visitors` (date, visitor, ip, country, region, city, host) VALUES ('".$date."', '".$visitor."', '".$ip."', '".$country."', '".$region."', '".$city."', '".$host."')")){     //printf("%d строк вставлено.\n", $mysqli->affected_rows); } else{ printf("Errorcode: %d\n", $mysqli->errno); };

Проверку можете включить на время наладки, потом я в нем необходимости не вижу. Теперь нам нужно взять значения для нашего счетчика посещений. Саму форму счетчика я взял с того же сайта где и сам первый счетчик в divы по вставлял следующие значения:

1. Для тех, кто зашел впервые или с другого ip-адреса:

if ($result1 = $mysqli -> query("SELECT * FROM `pre_visitors` WHERE (visitor NOT RLIKE  'bot') GROUP BY ip ORDER BY 'id'")){ //printf("%d строк вставлено.\n", $result->affected_rows); } $res1 = $result1 -> num_rows;

2. Для всего количества просмотров:

if ($result = $mysqli -> query("SELECT  MAX(id) AS id  FROM `pre_visitors` ORDER BY id")){ //printf("%d строк вставлено.\n", $result->affected_rows); } $res = $result -> fetch_array();

Ну и закрываем соединение с БД:

$mysqli -> close(); ?>

Кстати, не забываем подключить наш файл stats.php к index.php. Теперь визуализируем нашу таблицу. Создаем файл seestats.php и подключаемся к нашей БД:

<?php include_once ('core/config_class.php'); $mysqli = new mysqli($server, $user, $pswd, $db) or die("Не могу соединиться с MySQL."); $mysqli -> select_db($db) or die("Не могу подключиться к базе."); ?>

Теперь немного HTML, чтобы вывести все это на экран. Я еще добавил выбор количества выводимых строк.

<html>     <head>         <style type='text/css'>             td.zz {PADDING-LEFT: 3px; FONT-SIZE: 9pt; PADDING-TOP: 2px; FONT-FAMILY: Arial; }         </style>     </head>  <body> <center>     <form action="seestats.php" method="get">         <select name="visualcount">             <option value="10" selected></option>             <option value="50">50</option>             <option value="100">100</option>             <option value="250">250</option>             <option value="500">500</option>             <option value="1000">1000</option>         </select>         <input type="button" value="Запросить">     </form>

Далее обрабатываем нашу форму, запрашиваем все поля с нашей таблицы исключая ботов и повторяющиеся ip-адреса, также запрашиваем MAX id для концовки нашей таблицы.

<?php $lastid =  isset ($_GET['visualcount']) ? ($_GET['visualcount']) : '10'; if ($query = $mysqli->query("SELECT * FROM `pre_visitors` WHERE (visitor NOT RLIKE  'bot')  GROUP BY ip  ORDER BY 'id'  DESC LIMIT $lastid")){     //printf("%d строк получено.\n", $mysqli->affected_rows); } else{ printf("Errorcode: %d\n", $mysqli->errno); };  if ($result = $mysqli -> query("SELECT  MAX(id) AS id  FROM `pre_visitors` ORDER BY id")){ //printf("%d строк получено.\n", $result->affected_rows); } $num_rows = $query -> num_rows; $res = $result -> fetch_array(); ?>

Создаем таблицу, стили и размеры можете использовать какие вам нравятся:

<table width="680" cellspacing="1" cellpadding="1" border="0"            STYLE="table-layout:fixed">         <tr align = "center" bgcolor="#eeeeee">             <td class="zz" width="30"><b>№ п/п</b></td>             <td class="zz" width="90"><b>Время и дата</b></td>             <td class="zz" width="500"><b>Данные о посетителе</b></td>             <td class="zz" width="100"><b>IP/прокси</b></td>             <td class="zz" width="100"><b>Страна</b></td>             <td class="zz" width="100"><b>Регион</b></td>             <td class="zz" width="100"><b>Город</b></td>             <td class="zz" width="110"><b>Посещенный URL</b></td>         </tr>

Теперь через цикл заполняем нашу таблицу и закрываем соединение с БД:

<?php while($row = $query -> fetch_array()){     echo '<tr bgcolor="#eeeeee"><td class="zz">'.$row['id'].'</td>';     echo '<td class="zz">'.$row['date'].'</td>';     echo '<td class="zz">'.$row['visitor'].'</td>';     echo '<td class="zz">'.$row['ip'].'</td>';     echo '<td align = "center" class="zz">'.$row['country'].'</td>';     echo '<td align = "center" class="zz">'.$row['region'].'</td>';     echo '<td align = "center" class="zz">'.$row['city'].'</td>';     echo '<td class="zz">'.$row['host'].'</td></tr>'; }  echo '<tr bgcolor="#eeeeee"><td class="zz" colspan = "3" ><b>Количество новых посетителей</b></td>'; echo '<td align = "center"><b>'.$num_rows.'</b></td>'; echo '<td class="zz" colspan = "3" ><b>Общее количество посещений</b></td>'; echo '<td align = "center"><b>'.$res['id'].'</b></td></tr>'; echo '</table>'; echo '</center>'; echo '</body></html>'; $mysqli -> close(); ?>

Жаль только, что вы будете получать IP прокси-сервера, а не реального клиента.
Спасибо за внимание!

ссылка на оригинал статьи https://habrahabr.ru/post/313676/


Комментарии

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

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