- How to get the client IP address in PHP
- 36 Answers 36
- Get the client IP address using PHP [duplicate]
- 4 Answers 4
- Как в PHP узнать IP пользователя и определить его страну?
- Определение страны по ip с помощью Sypex Geo
- Определение города по ip с помощью Sypex Geo
- Определение страны и города по ip через сервис через сервис ipstack
- Как в PHP получить IP адрес сервера
- Пример реализации определения локации в CMS MODX
How to get the client IP address in PHP
How can I get the client IP address using PHP? I want to keep record of the user who logged into my website through his/her IP address.
See RFC6302 on recommendations about what to log, and specifically nowadays remember to log the port and not only the address.
A word of caution for those tracking users, in several regions of the globe ISPS are using CGNAT which makes it much more complicated to trust a mere IP address
You should use Abstract IP detection. The value is that it will let you know if the IP is behind a proxy or a VPN which I think is important. They have a PHP snippet you can copy your request from.
36 Answers 36
Whatever you do, make sure not to trust data sent from the client. $_SERVER[‘REMOTE_ADDR’] contains the real IP address of the connecting party. That is the most reliable value you can find.
However, they can be behind a proxy server in which case the proxy may have set the $_SERVER[‘HTTP_X_FORWARDED_FOR’] , but this value is easily spoofed. For example, it can be set by someone without a proxy, or the IP can be an internal IP from the LAN behind the proxy.
This means that if you are going to save the $_SERVER[‘HTTP_X_FORWARDED_FOR’] , make sure you also save the $_SERVER[‘REMOTE_ADDR’] value. E.g. by saving both values in different fields in your database.
If you are going to save the IP to a database as a string, make sure you have space for at least 45 characters. IPv6 is here to stay and those addresses are larger than the older IPv4 addresses.
(Note that IPv6 usually uses 39 characters at most but there is also a special IPv6 notation for IPv4 addresses which in its full form can be up to 45 characters. So if you know what you are doing you can use 39 characters, but if you just want to set and forget it, use 45).
Nice answer! I am already using $_SERVER[‘REMOTE_ADDR’] for my server, and I like that you included another way, plus the benefits and disadvantages.
Note: REMOTE_ADDR might not contain the real IP of the TCP connection. This entirely depends on your SAPI. Ensure that your SAPI is properly configured such that $_SERVER[‘REMOTE_ADDR’] actually returns the IP of the TCP connection. Failing that might give rise to some serious vulnerabilities, for example, StackExchange used to grant admin access by checking REMOTE_ADDR to see if it matches «localhost», unfortunately the SAPI’s config.
. had a vulnerability (it takes HTTP_X_FORWARDED_FOR as input) which allows non-admins to gain admin access by altering the HTTP_X_FORWARDED_FOR header. Also see blog.ircmaxell.com/2012/11/anatomy-of-attack-how-i-hacked.html
@EmilVikström I Tried echoing everything — $_SERVER[«HTTP_CLIENT_IP»]; $_SERVER[‘REMOTE_ADDR’]; $_SERVER[‘HTTP_X_FORWARDED_FOR’]; $_SERVER[‘HTTP_X_FORWARDED’]; $_SERVER[‘HTTP_FORWARDED_FOR’]; $_SERVER[‘HTTP_FORWARDED’]; and $_SERVER[‘HTTP_X_CLUSTER_CLIENT_IP’]; — The ONLY ONE which is returning some IP value from BOTH — Direct access through my browser and through a Proxy server is the REMOTE_ADDR var. Rest all 6 vars are coming as BLANKS. What is being missed here? .
$_SERVER[‘REMOTE_ADDR’] may not actually contain real client IP addresses, as it will give you a proxy address for clients connected through a proxy, for example. That may well be what you really want, though, depending what your doing with the IPs. Someone’s private RFC1918 address may not do you any good if you’re say, trying to see where your traffic is originating from, or remembering what IP the user last connected from, where the public IP of the proxy or NAT gateway might be the more appropriate to store.
There are several HTTP headers like X-Forwarded-For which may or may not be set by various proxies. The problem is that those are merely HTTP headers which can be set by anyone. There’s no guarantee about their content. $_SERVER[‘REMOTE_ADDR’] is the actual physical IP address that the web server received the connection from and that the response will be sent to. Anything else is just arbitrary and voluntary information. There’s only one scenario in which you can trust this information: you are controlling the proxy that sets this header. Meaning only if you know 100% where and how the header was set should you heed it for anything of importance.
Having said that, here’s some sample code:
if (!empty($_SERVER['HTTP_CLIENT_IP'])) < $ip = $_SERVER['HTTP_CLIENT_IP']; >elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) < $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; >else
Editor’s note: Using the above code has security implications. The client can set all HTTP header information (ie. $_SERVER[‘HTTP_. ) to any arbitrary value it wants. As such it’s far more reliable to use $_SERVER[‘REMOTE_ADDR’] , as this cannot be set by the user.
Get the client IP address using PHP [duplicate]
But I see it can not give the correct IP address using this. I get my IP address and see it is different from my IP address and I can also see my IP address in some website like:
I paste the IP address which give my PHP function but this website shows no result about this. How does this problem come about and how can I get IP address of the client?
If you are on a local server it will be different (eg: 192.168.xxx.xxx), because you check from whatsmyip you are getting your isp ip they supplied to you.
On your computer you’ll see your private IP (192..) and on websites you’ll your public IP (84. ). In general your public IP is the only interesting one.
Again, not really a duplicate, seeing as how this is the best ranked by Google. Stackoverflow guys, come on. «Marked as Duplicate» happens too often. If this ranks better, it’s for good reason. Google has spoken.
4 Answers 4
The simplest way to get the visitor’s/client’s IP address is using the $_SERVER[‘REMOTE_ADDR’] or $_SERVER[‘REMOTE_HOST’] variables.
However, sometimes this does not return the correct IP address of the visitor, so we can use some other server variables to get the IP address.
The below both functions are equivalent with the difference only in how and from where the values are retrieved.
getenv() is used to get the value of an environment variable in PHP.
// Function to get the client IP address function get_client_ip()
$_SERVER is an array that contains server variables created by the web server.
// Function to get the client IP address function get_client_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. Вставим в этот файл следующий код:
5. Включим файл «get_country_code.php» в другие скрипты, в которых нужно реализовать выполнение кода в зависимости от принадлежности ip посетителя к той или иной стране.
require_once 'SxGeo/get_country_code.php'; if ($country_сode === 'RU') { // код для посетителей из России. } else { // код для посетителей из других стран. }
Определение города по ip с помощью Sypex Geo
Для определения города, потребуется загрузить архив с базой данных городов для Sypex Geo, распаковать его и загрузить на сервер.
Скрипт в этом случае будет следующий:
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 запросов в месяц.
Для получения бесплатного плана нажимаем на кнопку «GET FREE API KEY» и переходим на страницу, на которой нужно заполнить регистрационную карточку.
После регистрации, на личной странице ipstack вам будет назначен «API Access Key», который нужно скопировать. Он нам потребуется при создании php скрипта.
Как в PHP получить IP адрес сервера
Узнать IP адрес сервера в PHP можно с помощью следующей инструкции:
// сохраним IP адрес сервера в переменную $ip_server $ip_server = $_SERVER['SERVER_ADDR']; // выведем IP адрес сервера на экран $echo $ip_server;
Пример реализации определения локации в CMS MODX
В качестве примере рассмотрим, как в CMS MODX Revolution можно очень просто без сторонних сервисов осуществить определение страны посетителя. Разработаем решение на базе Sypex Geo.
1. Для этого сначала нужно загрузить Sypex Geo в проект:
Файл «SxGeo.php» – это основной скрипт, а «SxGeo.dat» – это база стран. Этих двух файлов достаточно для определения страны пользователя по его ip. Дополнительно в каталоге SxGeo ещё расположен файл «SxGeoCity.dat», данный файл в текущей реализации не нужен, он может потребовать, если в проекте потребуется определять не только страну пользователя, а ещё его регион и город.
2. Создадим сниппет, например «get_location.php». В качестве примера организуем это с помощью файлов. Для этого нужно чтобы был установлен pdoTools и в настройках включена опция «Использовать Fenom на страницах».
Код сниппета «get_location.php»:
getCountry($ip); unset($SxGeo); $modx->setPlaceholder('countrycode', $country); return;
Поместим файл «get_location.php» в каталог /core/elements/snippets/ .
Данный сниппет будет определять страну и помещать его код в плейсхолдер countrycode .
3. После этого в нужных шаблонах поместим код вызова сниппета и сохранение значение плейсхолдера countrycode в переменную $country_code .
{$_modx->runSnippet('@FILE snippets/get_location.php')} {set $country_code = $_modx->getPlaceholder('countrycode')}
Всё теперь чтобы написать логику достаточно использовать эту переменную.
{if $country_code === 'UA'} Код для Украины {else} Код для других стран {/if}