2011-07-16 71 views
11

可能重复:
What is the most accurate way to retrieve a user's correct IP address in PHP?功能得到用户的IP地址

有没有在PHP没有更好的功能得到用户的IP地址? 这是我使用的那一刻

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); 
} 
+3

“更好”是什么意思?你有哪些代码需要改进? – Jon

+1

你从哪里得到这个功能?你为什么使用它?什么应该是坏的呢?你遇到过任何问题吗? – hakre

+0

@Jon - 缩进,开始。 ;-) – Spudley

回答

10

那么,你的函数应该像预期的那样,但这里有一些建议:

// 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"); 
} 
+0

doens't正常工作 – dino

+0

忘了一个;返回后$ tmp – nikksan

32

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; 
       } 
      } 
     } 
    } 
} 

检查对于IP(按顺序):

  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

记住,只有IP地址,你可以放心的是一名来自未来。

+4

为什么最后检查'REMOTE_ADDR'呢? – Anther

+0

@Anther:当用户不在代理之后时。 –

+0

真棒!它运作良好:)谢谢 – dino