【问题标题】:inet_pton replacement function for php 5.2.17 in windowswindows中php 5.2.17的inet_pton替换功能
【发布时间】:2013-01-05 17:05:17
【问题描述】:

在 PHP 中的 replacement alternative for inet_pton() 上,给出以下代码:

<?php
function inet_pton($ip)
{
    # ipv4
    if (strpos($ip, '.') !== FALSE) {
        $ip = pack('N',ip2long($ip));
    }
    # ipv6
    elseif (strpos($ip, ':') !== FALSE) {
        $ip = explode(':', $ip);
        $res = str_pad('', (4*(8-count($ip))), '0000', STR_PAD_LEFT);
        foreach ($ip as $seg) {
            $res .= str_pad($seg, 4, '0', STR_PAD_LEFT);
        }
        $ip = pack('H'.strlen($res), $res);
    }
    return $ip;
}
?>

但是当使用以下测试代码进行测试时,它显示并非所有条目都是正确的:

<?php
$arrIPs = array(
        "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
        "fe80:01::af0",
        "::af0",
        "192.168.0.1",
        "0000:0000:0000:0000:0000:0000:192.168.0.1");
foreach($arrIPs as $strIP) {
    $strResult = bin2hex(inet_pton($strIP));
    echo "From: {$strIP} to: {$strResult}<br />\n";
}
/*
From: 2001:0db8:85a3:0000:0000:8a2e:0370:7334 to: 20010db885a3000000008a2e03707334
From: fe80:01::af0 to: 0000000000000000fe80000100000af0 //Incorrect
From: ::af0 to: 00000000000000000000000000000af0
From: 192.168.0.1 to: c0a80001
From: 0000:0000:0000:0000:0000:0000:192.168.0.1 to: 00000000 //Incorrect
*/
?>

我不知道正确的 IPv6 语法,所以我更喜欢其他更了解 IPv6 和标准的人看看这个并告诉我它有什么问题?

【问题讨论】:

  • 我不太明白最后一段。 PEAR 是什么迫使您继续使用 PHP 5.2?为什么不能直接升级到 PHP 5.3? (请记住,PHP 5.2 已经两年不支持了;现在已经过时了)
  • @SDC 显然 5.3 没有为 Windows 提供 PEAR。如果我错了,请告诉我。
  • 还有:您上面显示的功能非常错误。如果地址以它开头,它只会正确扩展::。它错误地将 2001:db8::1 解释为 ::2001:db8:0:1
  • PEAR 是 PHP 软件生态系统中相当标准的一部分。它适用于所有平台上的所有 PHP 版本。无论如何,PEAR 本身不过是其他软件的安装平台; PEAR 安装的大部分软件在必要时可以不安装(现在很多 PHP 软件使用 Composer 或 PHAR 来安装而不是 PEAR,但这与他们使用的 PHP 版本无关)
  • @SDC 你能想象我曾为一家销售 1000 台... 带有 php 5.2 的 debian lenny 服务器的公司工作吗?你愿意远程升级这个 - 工作 - 服务器吗? “升级你的 PHP 版本”主要是一个想象的提示。没有什么值得

标签: php windows ipv6 replace


【解决方案1】:

我刚刚从php.net 下载了 PHP 5.3 安装程序,它在安装程序中包含了 PEAR。它只是默认没有安装:

【讨论】:

  • 嗯,也许这就是为什么我找不到手动安装 PEAR 的原因,当您安装 PHP 时,系统会提示您安装它。好的,所以我应该重新安装 PHP,但它并不能解决问题......我会给你 +1 来帮我找出这个问题
  • @FlorianMertens 我真的不明白为什么这个问题仍然悬而未决。您可以升级 PHP 并使用内置的 inet_pton() 函数。您为什么要寻找 PHP 5.2 解决方案?
  • @FlorianMertens 不要理解我的错误。我知道使用 PHP 5.2 有几个原因。 (与 SO 上的大多数回答者相反).. 告诉我一个原因,你就会得到你的功能
  • @hek2mgl 如果有人正在为 5.3 或更新的实时服务器开发站点,但只能访问安装了 5.2.* 的服务器上的小型虚拟预实时帐户,以测试或演示他的代码,该怎么办?给业务经理?可能是内部网络服务器,它们可以较少更新。这是一个原因,但还有其他原因。例如,我不安装 php 5.3 atm,只是因为根据经验,更改版本很困难,并且由于项目时间限制,我 PREFERCANT 升级非常小。等等等等……
  • 一个很好的理由是:“我们已经将我们的软件部署给(预期的)许多可能不愿意或无法更新其服务器操作系统的客户。但我真的非常需要这个功能。”如果你只需要一个PHP5.3的测试环境,可以考虑安装VirtualBox。
【解决方案2】:

这段代码会做的很好:

function inet_pton($ip){
    # ipv4
    if (strpos($ip, '.') !== FALSE) {
        if (strpos($ip, ':') === FALSE) $ip = pack('N',ip2long($ip));
        else {
            $ip = explode(':',$ip);
            $ip = pack('N',ip2long($ip[count($ip)-1]));
        }
    }
    # ipv6
    elseif (strpos($ip, ':') !== FALSE) {
        $ip = explode(':', $ip);
        $parts=8-count($ip);
        $res='';$replaced=0;
        foreach ($ip as $seg) {
            if ($seg!='') $res .= str_pad($seg, 4, '0', STR_PAD_LEFT);
            elseif ($replaced==0) {
                for ($i=0;$i<=$parts;$i++) $res.='0000';
                $replaced=1;
            } elseif ($replaced==1) $res.='0000';
        }
        $ip = pack('H'.strlen($res), $res);
    }
    return $ip;
}

结果:

From: 2001:0db8:85a3:0000:0000:8a2e:0370:7334 to:
string '20010db885a3000000008a2e03707334' (length=32)

From: fe80:01::af0 to:
string 'fe800001000000000000000000000af0' (length=32)

From: ::af0 to:
string '00000000000000000000000000000af0' (length=32)

From: 192.168.0.1 to:
string 'c0a80001' (length=8)

From: 0000:0000:0000:0000:0000:0000:192.168.0.1 to:
string 'c0a80001' (length=8)

【讨论】:

  • 它与一些现有代码配合得非常好!非常感谢。
  • 不客气,请记住,当出现双格式 IPv6 时,它总是会选择 IPv4。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-17
  • 2013-05-18
相关资源
最近更新 更多