2011-07-16 102 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