13

Possible Duplicate:
What is the most accurate way to retrieve a user's correct IP address in PHP?

Is there any better function in php to get user ip address? this is what i use at the moment

function GetIP()
{
if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown"))
$ip = getenv("HTTP_CLIENT_IP");
else if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown"))
$ip = getenv("HTTP_X_FORWARDED_FOR");
else if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown"))
$ip = getenv("REMOTE_ADDR");
else if (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown"))
$ip = $_SERVER['REMOTE_ADDR'];
else
$ip = "unknown";
return($ip);
}
Community
  • 1
  • 1
Frank Nwoko
  • 3,816
  • 5
  • 24
  • 33

2 Answers2

45

Adapted from this answer:

function GetIP()
{
    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 (array_map('trim', explode(',', $_SERVER[$key])) as $ip)
            {
                if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false)
                {
                    return $ip;
                }
            }
        }
    }
}

Checks for IPs (in order) in:

  1. HTTP_CLIENT_IP
  2. HTTP_X_FORWARDED_FOR
  3. HTTP_X_FORWARDED
  4. HTTP_X_CLUSTER_CLIENT_IP
  5. HTTP_FORWARDED_FOR
  6. HTTP_FORWARDED
  7. REMOTE_ADDR

Remember that the only IP address you can trust is the one coming from $_SERVER['REMOTE_ADDR'].

Community
  • 1
  • 1
Alix Axel
  • 151,645
  • 95
  • 393
  • 500
  • 4
    Why does it check `REMOTE_ADDR` last then? – Anther Feb 03 '13 at 06:13
  • @Anther: For when the user isn't behind a proxy. – Alix Axel Feb 03 '13 at 10:20
  • what is the return value's data type ? – Divyanshu Jimmy Jul 28 '18 at 08:56
  • Very good approach to get IP address but I've made some changes, I am working in development environment and my IP address is IP V6 ::1 (equal to 127.0.0.1).. It was not passed in this function.. So I added following lines right after foreach loop.. if ( isset( $_SERVER['REMOTE_ADDR'] ) ) { return $_SERVER['REMOTE_ADDR']; } return ''; – Shakeel Ahmed Nov 13 '19 at 07:21
11

Well, your function should behave as expected, but here are some suggestions:

// lowercase first letter of functions. It is more standard for PHP
function getIP() 
{
    // populate a local variable to avoid extra function calls.
    // NOTE: use of getenv is not as common as use of $_SERVER.
    //       because of this use of $_SERVER is recommended, but 
    //       for consistency, I'll use getenv below
    $tmp = getenv("HTTP_CLIENT_IP");
    // you DON'T want the HTTP_CLIENT_ID to equal unknown. That said, I don't
    // believe it ever will (same for all below)
    if ( $tmp && !strcasecmp( $tmp, "unknown"))
        return $tmp;
        
    $tmp = getenv("HTTP_X_FORWARDED_FOR");
    if( $tmp && !strcasecmp( $tmp, "unknown"))
        return $tmp;
        
    // no sense in testing SERVER after this. 
    // $_SERVER[ 'REMOTE_ADDR' ] == gentenv( 'REMOTE_ADDR' );
    $tmp = getenv("REMOTE_ADDR");
    if($tmp && !strcasecmp($tmp, "unknown"))
        return $tmp;
        
    return("unknown");
}
Arthur Shlain
  • 961
  • 10
  • 23
cwallenpoole
  • 79,954
  • 26
  • 128
  • 166