2

PHP の 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 と標準について詳しく知っている他の誰かがこれを見て、何が問題なのか教えてくれると思いますか?

4

2 に答える 2

4

php.netから PHP 5.3 インストーラーをダウンロードしたところ、インストーラーに PEAR が含まれています。デフォルトではインストールされていません:

PHP 5.3 PEAR インストール オプション

于 2013-01-22T23:10:46.527 に答える
3

このコードはそれを正しく行います:

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)
于 2013-01-28T18:30:48.417 に答える