【问题标题】:IP addresses get stored as 0 when converting with PHP ip2long function使用 PHP ip2long 函数转换时,IP 地址存储为 0
【发布时间】:2012-06-27 23:17:24
【问题描述】:

MySQL 中的 newsletter_ip 字段设置为 UNSIGNED INT (10)。我也尝试过 INET_ATON 来格式化数据,但我的结果总是看起来像 this

这是我的部分处理代码:

//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 格式化之前我也尝试过这个 sn-p,但无济于事:

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

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

【问题讨论】:

标签: php mysql ip ip-address


【解决方案1】:

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

注意:

由于 PHP 的整数类型是有符号的,而且很多 IP 地址在 32 位架构上会产生负整数,所以需要使用 sprintf() 或 printf() 的 "%u" 格式化器来获取未签名的 IP 地址。

您将其存储为 unsigned int,这就是您看到只有零的原因。对于处理 IPv6 的标准且干净的解决方案,其他人已经给出了解决方案。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 代理无法删除$_SERVER['REMOTE_ADDR']。是服务器端。 Apache 无所不知。
      • 如果是同一台机器上web服务器前面的本地代理,总是设置为127.0.0.1,例如。
      • 你会知道这个代理在同一台机器上运行,但无论如何,127.0.0.1 仍然是一个 IP 地址。
      【解决方案4】:

      让 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."')";
      

      【讨论】:

        【解决方案5】:

        使用 varchar(15) as min... 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;
        }
        

        【讨论】:

          【解决方案6】:

          您将 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 = 要地址的号码

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-02-25
            • 1970-01-01
            • 1970-01-01
            • 2011-10-30
            • 2017-07-01
            相关资源
            最近更新 更多