使用PHP的IP地址不可靠

时间:2011-08-07 05:20:35

标签: php javascript mysql codeigniter geolocation

我使用来自(http://www.iplocationtools.com)的javascript API来提供来自访问者IP的位置数据。出于某种原因,他们的API不会给我访问者的实际IP,只有其他信息,这就是为什么我必须使用PHP和CodeIgniter来给我IP。

所以我使用CodeIgniter / PHP来获取访问者的IP,并使用PHP的ip2long([ip code igniter给我])将其与上面的位置数据一起添加到数据库中

我的数据库表看起来像这样:http://pulse.media.mit.edu/images/1.png

哪个错了?我很想相信CodeIgniter是错的,因为它给了我很多次相同的IP。年龄和性别是自我报告的,我怀疑一个人正在编造所有这些信息。

在一天结束时,我们真正需要的只是用户IP和位置,最好是来自同一来源,因此我们不会复合错误。

有人对如何做到这一点有更好的想法吗?

编辑:这是我用来从CodeIgniter获取IP地址的代码

$data['ip_address'] = ip2long($this->input->ip_address());
$this->pulse_model->voter_info($data);

然后,voter_info函数将其插入到数据库中,并将其存储为INT(11)。

这是函数ip_address:

function ip_address()     {         if($ this-> ip_address!== FALSE)         {             返回$ this-> ip_address;         }

    if (config_item('proxy_ips') != '' && $this->server('HTTP_X_FORWARDED_FOR') && $this->server('REMOTE_ADDR'))
    {
        $proxies = preg_split('/[\s,]/', config_item('proxy_ips'), -1, PREG_SPLIT_NO_EMPTY);
        $proxies = is_array($proxies) ? $proxies : array($proxies);

        $this->ip_address = in_array($_SERVER['REMOTE_ADDR'], $proxies) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];
    }
    elseif ($this->server('REMOTE_ADDR') AND $this->server('HTTP_CLIENT_IP'))
    {
        $this->ip_address = $_SERVER['HTTP_CLIENT_IP'];
    }
    elseif ($this->server('REMOTE_ADDR'))
    {
        $this->ip_address = $_SERVER['REMOTE_ADDR'];
    }
    elseif ($this->server('HTTP_CLIENT_IP'))
    {
        $this->ip_address = $_SERVER['HTTP_CLIENT_IP'];
    }
    elseif ($this->server('HTTP_X_FORWARDED_FOR'))
    {
        $this->ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];
    }

    if ($this->ip_address === FALSE)
    {
        $this->ip_address = '0.0.0.0';
        return $this->ip_address;
    }

    if (strpos($this->ip_address, ',') !== FALSE)
    {
        $x = explode(',', $this->ip_address);
        $this->ip_address = trim(end($x));
    }

    if ( ! $this->valid_ip($this->ip_address))
    {
    $this->ip_address = '0.0.0.0';
    }
    return $this->ip_address;
}

3 个答案:

答案 0 :(得分:6)

$_SERVER['REMOTE_ADDR']是用于返回查看页面的人的IP地址的PHP代码。

答案 1 :(得分:2)

如果IPv4地址无效,则ip2long()的旧版本将返回-1。您可能希望使用inet_pton,并将用于保存它的字段扩展为128位。

答案 2 :(得分:1)

根据您的代码,如果IP无效或无法确定,$this->input->ip_address()似乎有可能返回'0.0.0.0'。但是,您的注释还表明您需要记录IP地址,即使上述方法返回'0.0.0.0'。

首先,我建议您查看$this->input->ip_address()$this->valid_ip()是否按预期工作。对于应被视为有效的IP,$this->valid_ip()是否返回false?

其次,如果$_SERVER['REMOTE_ADDR']返回'0.0.0.0',我会更新您的代码,以便始终回归$this->input->ip_address()

$ip_address = $this->input->ip_address();
if($ip_address == '0.0.0.0') {
    $ip_address = $_SERVER['REMOTE_ADDR'];
}
$data['ip_address'] = ip2long($ip_address);
$this->pulse_model->voter_info($data);

或者,如果您愿意,则无​​法使用$this->input->ip_address()并按照@rockerest的建议行事,只需使用$_SERVER['REMOTE_ADDR']即可。

$data['ip_address'] = ip2long($_SERVER['REMOTE_ADDR']);
$this->pulse_model->voter_info($data);