How to get most accurate visitor's IP address in PHP

Posted by Stanislav Furman  on April 15, 2013

Web developers often need to get visitor's IP address to use it in web applications. This can be used in internal traffic analytics tools, or as a part of security measures.

Most common and standard method of getting visitor's IP address is getting the value "REMOTE_ADDR" from the global PHP array $_SERVER:


<?php
$visitor_ip = $_SERVER['REMOTE_ADDR'];

However, standard PHP $_SERVER['REMOTE_ADDR'] value not necessarily contains the originating visitor's IP address because, for example, visitor can use a proxy server to access your web site. Using PHP we could try to detect user's IP address even if he uses proxy, but keep in mind that there is no guarantee that IP address that you get is 100% accurate (e.g. proxy can be anonymous).

Lets try to determne visitor's IP address using PHP array $_SERVER and some extra HTTP headers. There is a few values in the $_SERVER variable that could help. For example, the HTTP_X_FORWARDED HTTP header field which is identifying the originating IP address of a visitor accessing your web application via an HTTP proxy.

There is a few more HTTP header fields that could be used. We can use them one by one and see if there is a value that looks like an IP address: HTTP_CLIENT_IP, HTTP_X_FORWARDED_FOR, HTTP_X_FORWARDED, HTTP_X_CLUSTER_CLIENT_IP, HTTP_FORWARDED_FOR, HTTP_FORWARDED. Note that HTTP_X_FORWARDED_FOR can be comma delimited list of IPs.

Keeping all above in mind, here is an example of a function that tries to get most accurate visitor's IP address:


<?php
function getUserIp()
{
  $arr_keys = array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR');
  foreach ($arr_keys as $key) {
    if (array_key_exists($key, $_SERVER) === true){
      foreach (explode(',', $_SERVER[$key]) as $ip){
	if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false){
	  return trim($ip);;
	}
      }
    }
  }
}

The function above is commonly used by web devlopers. Your IP address also just has been detected using the function above. :-P


Leave your comment

Fields with * are required.

* When you submit a comment, you agree with Terms and Conditions of Use.