В этой статье рассмотрим, как в PHP можно узнать IP клиента и сервера, а также разберём как зная IP клиента определить его страну и город.

Как в PHP получить IP адрес посетителя сайта?

Получить IP адрес клиента в PHP можно через суперглобальный массив $_SERVER. В этом массиве IP адрес посетителя доступен через ключ REMOTE_ADDR.

// сохраним в переменную ip значение IP адреса клиента
$ip = $_SERVER['REMOTE_ADDR'];

Но, если клиент использует прокси-сервер, то значение $_SERVER['REMOTE_ADDR'] будет содержать IP последнего прокси-сервера, через который клиент попал на сайт.

В этом случае, чтобы узнать IP посетителя можно попробовать использовать $_SERVER['HTTP_CLIENT_IP'] и $_SERVER['HTTP_X_FORWARDED_FOR']. HTTP_CLIENT_IP и HTTP_X_FORWARDED_FOR – это заголовки, содержащие IP адрес пользователя. Данные заголовки устанавливает прокси-сервер. Обычно прокси-сервер устанавливает один из них. Данным в этих заголовках можно доверять, только если прокси-сервер надёжный. В противном случае, им доверять не стоит, т.к. их можно очень просто подделать. В этом случае лучше просто использовать $_SERVER['REMOTE_ADDR'] или сохранять в базу как $_SERVER['REMOTE_ADDR'], так и заголовок, устанавливаемый прокси-сервером.

function getIp() {
  $keys = [
    'HTTP_CLIENT_IP',
    'HTTP_X_FORWARDED_FOR',
    'REMOTE_ADDR'
  ];
  foreach ($keys as $key) {
    if (!empty($_SERVER[$key])) {
      $ip = trim(end(explode(',', $_SERVER[$key])));
      if (filter_var($ip, FILTER_VALIDATE_IP)) {
        return $ip;
      }
    }
  }
}

$ip = getIp();
// выведем IP клиента на экран
echo 'ip = ' . $ip;  

Определение страны по ip с помощью Sypex Geo

Основные шаги по созданию php скрипта, с помощью которого можно будет определять страну по ip:

1. Скачаем Sypex Geo для PHP и базу данных стран. Sypex Geo распространяется по лицензии BSD, т.е. является абсолютно бесплатным.

2. Распакуем архивы и загрузим на сервер файлы «SxGeo.php» и «SxGeo.dat». В качестве примера, создадим на сервере папку SxGeo и загрузим эти файлы в неё.

3. Создадим свой скрипт, например, «get_country_code.php».

4. Вставим в этот файл следующий код:

<?php
  
// получим ip клиента
$ip = $_SERVER['REMOTE_ADDR']; 
// подключим файл SxGeo.php
require_once 'SxGeo.php';
// создадим объект SxGeo (1 аргумент – имя файла базы данных, 2 аргумент – режим работы: SXGEO_FILE (по умолчанию), SXGEO_BATCH  (пакетная обработка, увеличивает скорость при обработке множества IP за раз), SXGEO_MEMORY (кэширование БД в памяти, еще увеличивает скорость пакетной обработки, но требует больше памяти, для загрузки всей базы в память).
$SxGeo = new SxGeo('SxGeo.dat', SXGEO_BATCH | SXGEO_MEMORY);
// получаем двухзначный ISO-код страны (RU, UA и др.)
$country_code = $SxGeo->getCountry($ip);

5. Включим файл «get_country_code.php» в другие скрипты, в которых нужно реализовать выполнение кода в зависимости от принадлежности ip посетителя к той или иной стране.

require_once 'SxGeo/get_country_code.php';
if ($country_сode === 'RU') {
  // код для посетителей из России...
} else {
  // код для посетителей из других стран...
}

Определение города по ip с помощью Sypex Geo

Для определения города, потребуется загрузить архив с базой данных городов для Sypex Geo, распаковать его и загрузить на сервер.

Скрипт в этом случае будет следующий:

<?php

// узнаем ip посетителя
$ip = $_SERVER['REMOTE_ADDR'];
require_once 'SxGeo.php';
// подключаем файл с базой данных городов
$SxGeo = new SxGeo('SxGeoCity.dat', SXGEO_BATCH | SXGEO_MEMORY);
$city = $SxGeo->get($ip);
// также можно использовать следующий код
// $SxGeo->getCity($ip);

// широта
$lat = $city['city']['lat'];
// долгота
$lon = $city['city']['lon'];
// название города на русском языке
$city_name_ru = $city['city']['name_ru'];
// название города на английском языке
$city_name_en = $city['city']['name_en'];
// ISO-код страны
$country_code = $city['country']['iso'];

// для получения информации более полной информации (включая регион) можно осуществить через метод getCityFull
$city = $SxGeo->getCityFull($ip);
// название региона на русском языке
$region_name_ru = $city['region']['name_ru'];
// название региона на английском языке
$region_name_en = $city['city']['name_en'];
// ISO-код региона
$region_name_iso = $city['city']['iso'];

Для автоматического обновления баз можно воспользоваться этим архивом. В этом архиве находится php скрипт. Этот скрипт необходимо настроить, т.е. указать в нём URL для скачивания базы и пути к файлам на сервере. После этого загрузить его на сервер и настроить его запуск по расписанию с помощью cron.

Определение страны и города по ip через сервис через сервис ipstack

Рассмотрим ещё один вариант определения в php местоположения по ip посетителя, но уже не через Sypex Geo, а с помощью сервиса ipstack.

Сервис ipstack имеет бесплатный план, который позволяет обрабатывать до 10000 запросов в месяц.

Планы сервиса ipstack для определения страны и города посетителя по его ip

Для получения бесплатного плана нажимаем на кнопку «GET FREE API KEY» и переходим на страницу, на которой нужно заполнить регистрационную карточку.

После регистрации, на личной странице ipstack вам будет назначен «API Access Key», который нужно скопировать. Он нам потребуется при создании php скрипта.

<?php
// получим ip адрес клиента
$ip = $_SERVER['REMOTE_ADDR'];
// переменная $access_key должна содержать ваш API Access Key
$access_key = '...';
// инициализируем новый сеанс cURL
$ch = curl_init('http://api.ipstack.com/'.$ip.'?access_key='.$access_key.'');
// если нужно выбрать только страну, то можно так
//$ch = curl_init('http://api.ipstack.com/'.$ip.'?access_key='.$access_key.'&fields=country_code');
// устанавливаем параметр для указанного сеанса cURL
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// выполняем запрос cURL и сохраняем данные в $json
$json = curl_exec($ch);
// завершаем сеанс cURL
curl_close($ch);
// декодируем JSON ответ
$api_result = json_decode($json, true);

// получаем ISO-код страны
$county_code = $api_result['country_code'];
// получаем название региона
$region_name = $api_result['region_name'];
// получаем название города
$city = $api_result['city'];

Как в PHP получить IP адрес сервера?

Узнать IP адрес сервера в PHP можно с помощью следующей инструкции:

// сохраним IP адрес сервера в переменную $ip_server
$ip_server = $_SERVER['SERVER_ADDR'];
// выведем IP адрес сервера на экран
$echo $ip_server;