PHP中的客户端IP不正确

时间:2014-02-12 08:57:04

标签: php ip

在某些情况下,我在PHP中获得了客户端IP的奇怪结果。

大多数情况下的结果(预期结果):

192.123.132.123

错误结果类型1:

for="192.123.132.123"

错误结果类型2:

for="192.123.132.123:1232"

获取IP的代码:

<?php

function getIP(){
$ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '-';
$proxy = false;
if (!empty($_SERVER['HTTP_VIA']) || !empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $proxy = true;
} elseif (!empty($_SERVER['REMOTE_HOST'])) {
    $aProxyHosts = array('proxy','cache','inktomi');
    foreach ($aProxyHosts as $proxyName) {
    if (strpos($_SERVER['REMOTE_HOST'], $proxyName) !== false) {
        $proxy = true;
        break;
    }
    }
}
// Has the viewer come via an HTTP proxy?
if ($proxy) {
// Try to find the "real" IP address the viewer has come from
$aHeaders = array('HTTP_FORWARDED','HTTP_FORWARDED_FOR','HTTP_X_FORWARDED','HTTP_X_FORWARDED_FOR','HTTP_CLIENT_IP');
foreach ($aHeaders as $header) {
    if (!empty($_SERVER[$header])) {
        $ip = $_SERVER[$header];
        break;
    }
}
}
if (!empty($ip)) {
// The "remote IP" may be a list, ensure that
// only the last item is used in that case
$ip = explode(',', $ip);
$ip = trim($ip[count($ip) - 1]);
}
return $ip;
}

?>

我知道我可以清理结果以获得正确的值(IP),但我很困惑为什么会发生这种情况。

PS:192.123.132.123是用于解释该问题的任意IP。

1 个答案:

答案 0 :(得分:1)

您正在阅读任意HTTP标头...并非所有标头都包含纯粹的IP,有些是for=...形式,有些还包括端口。

  1. 使用任何HTTP标头代替$_SERVER['REMOTE_ADDR']意味着您只需发送HTTP标头即可允许任何人屏蔽/伪造其IP地址。您应该完全了解可以设置此类标头的位置,这通常意味着您知道它们是由您控制的代理设置的。在这种情况下,您显然不知道这些标头的来源,因此您不应该使用它们。
  2. 如果您决定使用HTTP标头,则应该知道要准确读取哪个标头以及它的格式。如果格式为for=...,则正确解析该格式。