【问题标题】:How can I simplify an IP address using PHP? Trying long2ip(ip2long(address))如何使用 PHP 简化 IP 地址?尝试 long2ip(ip2long(address))
【发布时间】:2019-02-06 00:30:50
【问题描述】:

我的系统包含一个第三方盒子,它存储 IP 地址并将它们与从我的 Web 界面发送的值进行比较。我有一个问题,用户将第三方盒子的网络掩码输入为 255.255.255.000,而盒子将其存储为 255.255.255.0。然而,下次盒子重新启动并被告知掩码包含 000 时,它会断定这些值不同,并更新其数据库并重新启动。并重新启动。并重新启动。

我的意图是通过将网络掩码以简化形式 255.255.255.0 存储在我自己的系统中来解决这个问题(作为另一个示例,将 010.001.002.005 存储为 10.1.2.5)。但我是 PHP 的新手。我尝试使用代码$mask = long2ip(ip2long($mask)) 将条目转换为标准化形式,但只得到了 0.0.0.0。我需要做一些特别的事情来将 IP 转换为 long 和 back 吗?有没有更好的方法来简化这个?

【问题讨论】:

  • 为什么不按点使用explode() 并为每个元素进行int 类型转换(这将删除前导零)?
  • @ka_lin 正如我所说,我是 PHP 新手。您能否将其扩展为处理该字段的真实代码并将其添加为可能的答案?谢谢
  • 为什么不在使用前验证用户输入?

标签: php ip2long


【解决方案1】:

要遵循 cmets 中 @ka_lin 的建议,只需将其分解为多个部分,将其转换为 int 将删除前导 0 并使用 implode 重建它...

$mask = implode(".", array_map("intval", explode(".", $mask)));

一个简单且开销较小的版本假设 IP 地址有 4 个部分...

list ($o1, $o2, $o3, $o4) = explode(".", $mask);
$mask = (int)$o1.".".(int)$o2.".".(int)$o3.".".(int)$o4;

这很困难,因为 010.001.002.005 是一个有效的 IP 地址,但也可能令人困惑(有时以 0 开头的数字是八进制)。

【讨论】:

    【解决方案2】:

    ip2long 出错时返回 false 并且它似乎没有将 000 检测为有效。由于255.255.255.000 未被检测为有效IP,因此它会返回false,因此long2ip(false) 不会吐出有效IP。

    您甚至可以在接受 IP 地址之前检查 ip2long(input) 是否返回 true。进行适当的验证可以防止无效 IP 破坏系统。尝试对所有可能的无效 IP 地址实施自动更正将比仅从一开始就强制执行有效 IP 困难得多。

    【讨论】:

    • 有趣。我希望 .000 有效,但并不简单。所以你说总是使用三个十进制数字是无效的,整数必须没有前导零? 010.001.002.005 不是有效的 IP 地址?如果这是真的,那么我肯定需要在逻辑路径中将验证移到更高的位置。
    • @Sinc 是的,我更新了我的答案,因为 000 实际上是有效的,但 ip2long 没有检测到它。
    • 您真的应该检查ip2long() 是否将!== false 返回为0.0.0.0 => 0。这也是为什么long2ip(false) => 0.0.0.0
    • @Sinc,inet_pton 也不能使用前导零,因此没有一个 php ip 库支持“000”地址。
    • @Devon,这似乎是对图书馆的狭隘看法。我认为进行双重转换将是获取简单 IP 地址的最简单方法。我可以想象一些编码器总是将 IP 打印为 %3d,所以库函数不支持它似乎很不幸。感谢您的检查。我必须将验证移到上游,并且可能会强制用户更正输入。
    【解决方案3】:

    注意:ip2long() 有一个问题:它不接受有效的 IP 地址 127.1(经典的表示法,但有效!)或 127.0.0.010(RFC 说无效,但大多数人将 010 视为八进制数)。

    gethostbyname() 的替代方案。但是gethostbyname() 也有问题:如果输入了无效的 ip(如127.0.0.1234),它会进行 DNS 查找并返回源,如果查找失败。

    解决方案可以是:

    long2ip(ip2long(gethostbyname($IP_ADDRESS)))
    

    我个人的解决方案是如下函数:

    function aton ( $addr )
    {
        $l = explode('.',$addr);
        switch (count($l))
        {
            case 0: return FALSE;
    
            case 1: return intval($l[0]) & 0xffffffff;
    
            case 2: return  ( intval($l[0]) << 24
                            | intval($l[1])
                            ) & 0xffffffff;
    
            case 3: return  ( intval($l[0]) << 24
                            | intval($l[1]) << 16
                            | intval($l[2])
                            ) & 0xffffffff;
    
            default: return ( intval($l[0]) << 24
                            | intval($l[1]) << 16
                            | intval($l[2]) <<  8
                            | intval($l[3])
                            ) & 0xffffffff;
        }
    }
    

    有了这个功能,你可以使用:

    long2ip(aton($IP_ADDRESS))
    

    顺便说一句,我从来没有遇到过像 255.255.255.0 这样的特殊 IP 地址的问题。

    【讨论】:

      猜你喜欢
      • 2012-06-27
      • 2016-12-22
      • 2021-08-10
      • 2021-02-26
      • 1970-01-01
      • 2014-10-14
      • 2013-02-21
      • 1970-01-01
      • 2015-05-20
      相关资源
      最近更新 更多