What is the most accurate way to retrieve a user's correct IP address in PHP?
Here is a shorter, cleaner way to get the IP address:
function get_ip_address(){
foreach (array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR') as $key){
if (array_key_exists($key, $_SERVER) === true){
foreach (explode(',', $_SERVER[$key]) as $ip){
$ip = trim($ip); // just to be safe
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false){
return $ip;
}
}
}
}
}
Your code seems to be pretty complete already, I cannot see any possible bugs in it (aside from the usual IP caveats), I would change the validate_ip()
function to rely on the filter extension though:
public function validate_ip($ip)
{
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) === false)
{
return false;
}
self::$ip = sprintf('%u', ip2long($ip)); // you seem to want this
return true;
}
Also your HTTP_X_FORWARDED_FOR
snippet can be simplified from this:
// check for IPs passing through proxies
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
{
// check if multiple ips exist in var
if (strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ',') !== false)
{
$iplist = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
foreach ($iplist as $ip)
{
if ($this->validate_ip($ip))
return $ip;
}
}
else
{
if ($this->validate_ip($_SERVER['HTTP_X_FORWARDED_FOR']))
return $_SERVER['HTTP_X_FORWARDED_FOR'];
}
}
To this:
// check for IPs passing through proxies
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
{
$iplist = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
foreach ($iplist as $ip)
{
if ($this->validate_ip($ip))
return $ip;
}
}
You may also want to validate IPv6 addresses.
PHP most accurate / safe way to get real user IP address in 2017
Short answer:
$ip = $_SERVER['REMOTE_ADDR'];
As of 2021 (and still) $_SERVER['REMOTE_ADDR'];
is the only reliable way to get users ip address, but it can show erroneous results if behind a proxy server.
All other solutions imply security risks or can be easily faked.
Get the client IP address using PHP
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() {
$ipaddress = '';
if (getenv('HTTP_CLIENT_IP'))
$ipaddress = getenv('HTTP_CLIENT_IP');
else if(getenv('HTTP_X_FORWARDED_FOR'))
$ipaddress = getenv('HTTP_X_FORWARDED_FOR');
else if(getenv('HTTP_X_FORWARDED'))
$ipaddress = getenv('HTTP_X_FORWARDED');
else if(getenv('HTTP_FORWARDED_FOR'))
$ipaddress = getenv('HTTP_FORWARDED_FOR');
else if(getenv('HTTP_FORWARDED'))
$ipaddress = getenv('HTTP_FORWARDED');
else if(getenv('REMOTE_ADDR'))
$ipaddress = getenv('REMOTE_ADDR');
else
$ipaddress = 'UNKNOWN';
return $ipaddress;
}
$_SERVER is an array that contains server variables created by the web server.
// Function to get the client IP address
function get_client_ip() {
$ipaddress = '';
if (isset($_SERVER['HTTP_CLIENT_IP']))
$ipaddress = $_SERVER['HTTP_CLIENT_IP'];
else if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
$ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
else if(isset($_SERVER['HTTP_X_FORWARDED']))
$ipaddress = $_SERVER['HTTP_X_FORWARDED'];
else if(isset($_SERVER['HTTP_FORWARDED_FOR']))
$ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
else if(isset($_SERVER['HTTP_FORWARDED']))
$ipaddress = $_SERVER['HTTP_FORWARDED'];
else if(isset($_SERVER['REMOTE_ADDR']))
$ipaddress = $_SERVER['REMOTE_ADDR'];
else
$ipaddress = 'UNKNOWN';
return $ipaddress;
}
Get correct IP address of user machine
Luthando Loot is right. The answer is present here:
Getting visitors country from their IP
However, it is located in answer but not in question.
if (isset($_SERVER['HTTP_CLIENT_IP']))
{
$real_ip_adress = $_SERVER['HTTP_CLIENT_IP'];
}
if (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
{
$real_ip_adress = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
else
{
$real_ip_adress = $_SERVER['REMOTE_ADDR'];
}
You should check this values in such order:
HTTP_CLIENT_IP
HTTP_X_FORWARDED_FOR
REMOTE_ADDR
It doesn't mean that you will precisely get his IP address. It can be easily hidden by anonymizer, proxy, ISP etc. However, it is much more efficient than loooking at REMOTE_ADDR only.
There are some other values in SERVER array. Actually, this question is a duplicate to this:
What is the most accurate way to retrieve a user's correct IP address in PHP?
Related Topics
How to Add PHP Code/File to Html(.Html) Files
How to Post Data in PHP Using File_Get_Contents
How to Filter an Array by a Condition
Gcm With PHP (Google Cloud Messaging)
Call to a Member Function Bind_Param() on a Non-Object
Failed to Connect to Mailserver At "Localhost" Port 25
PHP Regular Expressions: No Ending Delimiter '^' Found In
How to Use MySQLi Prepared Statements
Getting Visitors Country from Their Ip
Get Order Items and Wc_Order_Item_Product in Woocommerce 3
What Is the Size Limit of a Post Request
How to Log Errors and Warnings into a File
How to Add Elements to an Empty Array in PHP
Detecting Request Type in PHP (Get, Post, Put or Delete)
How to Generate in PHP All Combinations of Items in Multiple Arrays