使用 PHP ip2long 函数转换时,IP 地址存储为 0


IP addresses get stored as 0 when converting with PHP ip2long function

MySQL中的newsletter_ip字段设置为无符号INT (10)。我也尝试INET_ATON格式化数据,但我的结果总是像这样。

这是我处理代码的一部分:

//Retrieve data from user and create variables
$ip_orig = $_SERVER['REMOTE_ADDR'];
$ip = ip2long($ip_orig);
//Place into database
$sql = "INSERT INTO newsletter(newsletter_email, newsletter_ip, newsletter_date, newsletter_time) VALUES('".$email."', '".$ip."', '".$date."', '".$time."')";

在ip2long格式之前,我也尝试过这个片段,但无济于事:

if (!empty($_SERVER['HTTP_CLIENT_IP'])){
    $ip=$_SERVER['HTTP_CLIENT_IP'];
}elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){
    $ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
}else{
    $ip=$_SERVER['REMOTE_ADDR'];
}

任何帮助将不胜感激,谢谢!

对于问题的根本原因,ip2long 给出了一个有符号的 int,如 PHP 手册所述:

注意:

由于 PHP 的整数类型是有符号的,并且许多 IP 地址在 32 位架构上会导致负整数,因此您需要使用 sprintf() 或 printf() 的"%u"格式化程序来获取无符号 IP 地址的字符串表示形式。

你把它存储为一个无符号的int,这就是你看到ony zero的原因。对于处理IPv6的标准和干净的解决方案,其他人已经给出了解决方案。

由于 IP 地址中有几个点,或者它可能是 IPv6 地址,我建议您将newsletter_ip字段设置为 VARCHAR

现在,您的 IP 地址可能显示为 0,因为它们实际上不是整数。

在存储之前打印出 ip 会给你正确的值吗?如果没有,请检查是否存在从请求中删除此信息或重命名此信息的代理。

无论如何,长时间存储IP没有任何好处。如果对此字段使用字符串,则不应有明显的性能损失,该字符串更直接且更易于处理。当你在它的时候,为IPv6留出足够的空间;-)

让MySQL在服务器端使用INET_ATON转换IP怎么样?

//Retrieve data from user and create variables
$ip_orig = $_SERVER['REMOTE_ADDR'];
//Place into database
$sql = "INSERT INTO newsletter(newsletter_email, newsletter_ip, newsletter_date, newsletter_time) VALUES('".$email."', INET_ATON('".$ip."'), '".$date."', '".$time."')";
使用 varchar(

15) 作为最小值... varchar(45) 支持更新的 IPv6 地址,这也是我的 IP 函数:

function ip()
{
    if (!empty($_SERVER['HTTP_CLIENT_IP']))
    {
        $ip = $_SERVER['HTTP_CLIENT_IP'];
    } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
    {
        $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    }
    else
    {
        $ip = $_SERVER['REMOTE_ADDR'];
    }
    return $ip;
}
您将 long

存储为字符串,而不是 long。

您最好在MySQL本身中进行转换:

$sql = "INSERT INTO newsletter(newsletter_email, newsletter_ip, newsletter_date, newsletter_time) VALUES ('".$email."', INET_ATON('".$ip."'), '".$date."', '".$time."')";

要检索 IP 地址,请执行以下操作:

SELECT INET_NTOA(newsletter_ip) as newsletter_ip FROM newsletter;

INET_ATON = 地址到号码

INET_NTOA = 要地址的号码