A single line of PHP script is sufficient to get IP address using PHP, ‘most of the times’.
First I will present that one line PHP code, then show a tiny function which almost covers the rest of the cases. Followed by a discussion on privacy issues to get the IP address.
This article has the following,
<?php
$ipAddress = $_SERVER['REMOTE_ADDR'];
?>
$_SERVER is a PHP array which is set by the server. There is a possibility that this value may not have been set. Also be aware that, these headers can be easily spoofed by the users by setting an IP address themselves.
Following PHP script covers majority of the scenario and returns the user’s IP address.
<?php
/**
* Gets IP address.
*/
function getIpAddress()
{
$ipAddress = '';
if (! empty($_SERVER['HTTP_CLIENT_IP'])) {
// to get shared ISP IP address
$ipAddress = $_SERVER['HTTP_CLIENT_IP'];
} else if (! empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
// check for IPs passing through proxy servers
// check if multiple IP addresses are set and take the first one
$ipAddressList = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
foreach ($ipAddressList as $ip) {
if (! empty($ip)) {
// if you prefer, you can check for valid IP address here
$ipAddress = $ip;
break;
}
}
} else if (! empty($_SERVER['HTTP_X_FORWARDED'])) {
$ipAddress = $_SERVER['HTTP_X_FORWARDED'];
} else if (! empty($_SERVER['HTTP_X_CLUSTER_CLIENT_IP'])) {
$ipAddress = $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
} else if (! empty($_SERVER['HTTP_FORWARDED_FOR'])) {
$ipAddress = $_SERVER['HTTP_FORWARDED_FOR'];
} else if (! empty($_SERVER['HTTP_FORWARDED'])) {
$ipAddress = $_SERVER['HTTP_FORWARDED'];
} else if (! empty($_SERVER['REMOTE_ADDR'])) {
$ipAddress = $_SERVER['REMOTE_ADDR'];
}
return $ipAddress;
}
echo "IP Address: " . getIpAddress();
Rest of the article is for comprehensiveness. If you just want to get IP address using PHP, you can stop at this point. Copy the above script and carry on with your IP address journey.
IP address can be easily spoofed. It can come from behind a proxy server. CloudFlare like proxies can be involved. Localhost can return invalid IP address. So, if you want to validate an IP address, use the below script.
<?php
/**
* To validate if an IP address is both a valid and does not fall within
* a private network range.
*
* @param string $ip
*/
function isValidIpAddress($ip)
{
if (filter_var($ip, FILTER_VALIDATE_IP,
FILTER_FLAG_IPV4 |
FILTER_FLAG_IPV6 |
FILTER_FLAG_NO_PRIV_RANGE |
FILTER_FLAG_NO_RES_RANGE) === false) {
return false;
}
return true;
}
Following flowchart explains the flow of control to get IP address using PHP.
When the website is hosted using CloudFlare service, $_SERVER['REMOTE_ADDR']
will return the CloudFlare server’s IP address and not the user’s original IP address. So in such a situation, you can use the variable set by the CloudFlare server to get the IP address.
I have taken CloudFlare as example. There are many similar services. You need to talk to that service provider to know which request header they are setting and get the IP address accordingly.
if (isset($_SERVER["HTTP_CF_CONNECTING_IP"])) {
$_SERVER['REMOTE_ADDR'] = $_SERVER["HTTP_CF_CONNECTING_IP"];
$ipAddress = $_SERVER['REMOTE_ADDR'];
}
$_SERVER['REMOTE_ADDR']
is the most reliable variable from the above list of variables. REMOTE_ADDR
may not contain the real IP address of the TCP connection as well. It depends on the SAPI configuration.
If the user is behind a proxy server, HTTP_X_FORWARDED_FOR
will be set. But this can be easily spoofed by the user by setting an IP address he wishes to expose.
Even the variable X-Forwarded-For
or the Client-IP can be set by the user to any value he wishes.
Take an example of a shopping cart. You may display the product price according to the user’s country. In such a scenario, you may use the user’s IP address to determine the user’s country. In such a scenario, the code to get user’s IP address should be fool-proof.
When you are storing the IP address in the database, remember to have the field size as 45 for single IP. Because there is a possibility for IPv6 IP addresses. In its full form the IPv6 IP address can be 45 characters in length.
Using a hostname, we can get the server’s IP address using the PHP’s built-in function gethostbyname
. This returns the IPv4 address.
<?php
// to get IP address of a host
$ipAddress = gethostbyname('www.google.com');
echo "Google's IP Address is: " . $ipAddress;
?>
Google’s IP Address is: 142.250.67.36
The reverse is also possible by using gethostbyaddr()
.
Client’s IP address can be considered as private information in certain legislation. It depends on the land of law. You never know from which geographic region you will get users.
As per GDPR (Article 4, Point 1; and Recital 49), IP address is a personal data. I would suggest to inform the user and get consent to log the IP address. Also, call it out explicitly in your “Privacy Policy” document.
Explicitly state that you are collecting and logging the client user’s IP address and the reason for doing so.
A good understanding of the scenario in which you are going to get IP address of the user is important. Then understand that the end user can easily spoof his IP address. Third understand each server variables, from where the IP address is fetched. Last but not the least, explicitly call out in your privacy policy that you are getting the client user’s IP address.
Thanks for the informative write up.
Welcome Francis.
And if a user uses a VPN do we than get the IP-address set by the VPN?
Hi Ralph,
Yes, when a user uses a VPN service to browse the site, then you cannot predict the result.
I use almost same class but i integrated isset($_SERVER[“HTTP_CF_CONNECTING_IP”]) within the class then use ELSE .. coz most websites use Cloudflare . :)
Hi MalluCafe,
Thank you for sharing the information. It will help for Cloudflare hosted websites. Thanks.
Hello! such a good knowledge!
If i want to use this code on the real web server and shows my client ip address and save it in the database, how to do it? is it possible?
Hi Nana,
Thank you. Sure, you can store the client IP address in the database. You need to use MySQLi or PDO to create a connection and insert it in a table. https://phppot.com/php/php-crud-with-mysql/ refer this article for insert part.
Thanks for this
Welcome Octagon.
Nice Article
Thank you Kumar.