1

ユーザー登録、投稿、アップロードなどと一緒に IP アドレスを保存したいです。私が作成した以前のサイトは、IPv4 が私の唯一の関心事であったため、常に使用ip2long/long2ipして保存していました。UNSIGNED INTそのため、IP アドレスをip2longで実行して保存し、取得したら を使用しますlong2ip。しかし今は、それがもう少し将来性のあるものであることを確認し、IPv4 と IPv6 の両方に取り組みたいと考えています。

これは、IPv4 と IPv6 の両方を処理するためにこれまでに思いついた関数です。

function ipCheck()
{
    // Get IP Address
        if (!empty($_SERVER['HTTP_CLIENT_IP'])) // Shared client
        {
            $ipAddress = $_SERVER['HTTP_CLIENT_IP'];
        }
        else if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) // Proxy address
        {
            $ipAddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
        }
        else
        {
            $ipAddress = $_SERVER['REMOTE_ADDR']; // User viewing
        }

    // Over IP for testing
        /*
            IP Examples for testing

            IPv4:   64.233.160.0
            IPv6:   2607:f0d0:1002:51::4
            IPv6:   2607:f0d0:1002:0051:0000:0000:0000:0004
        */

        $ipAddress = '2607:f0d0:1002:0051:0000:0000:0000:0004'; // Comment out this line for actual IP

    // Validate IP
        if (filter_var($ipAddress, FILTER_VALIDATE_IP))
        {
            if (strpos($ipAddress, ':') !== false)
            {
                $ipType = 'IPv6';
                $ipAddressDB = inet_pton($ipAddress);
            }
            else
            {
                $ipType = 'IPv4';
                $ipAddressDB = ip2long($ipAddress);
            }
        }
        else
        {
            $ipType = 'Invalid';
            $ipAddressDB = $ipAddress;
        }

    // Display results
        echo '<strong>IP Type: </strong>'.$ipType.'<br />',
             '<strong>IP Address: </strong>'.$ipAddress.'<br />',
             '<strong>DatabaseIP: </strong>'.$ipAddressDB;
}

ipCheck();

私は個人的に IPv6 アドレスを持っていないので$ipAddress、テスト目的で変数をオーバーライドしました。

IPv4 アドレスではすべて正常に動作しますが、IPv6 アドレスでは、テスト IPを使用すると$ipAddressDB値が返され、その理由が本当にわかりません。私は間違って使用していますか?それに何かを追加する必要がありますか?テストIPv6アドレスが原因ですか?&(diamond-with-question-mark)(diamond-with-question-mark)Q2607:f0d0:1002:0051:0000:0000:0000:0004inet_pton

2 つの列に格納する必要があるため、データベース IP 用に 2 つの変数を作成します。IPv4 の場合は、それを変数 1 に割り当て、変数 2 を空白のままにします。それでIPv6なら分割して、前半を変数1、後半を変数2に入れます。それから挿入/選択するとき、2番目の列が空の場合、IPv4アドレスと見なすことができますか?

私がやろうとしていることが実際に実行可能かどうか、100% 確信が持てませんか? そうでない場合は、IPv6 アドレスをそのまま ( なしでinet_pton) 取得し、そのように分割する方がよいでしょうか?

4

1 に答える 1

1

アドレスをバイナリ形式で表示しています。「&」はUTF-8 0x26、0xf0と0xd0は無効なUTF-8(「�」で表示)、「Q」はUTF-8 0x51、その他のバイトはnull表示です。格納する前に、バイト文字列を 16 進数としてエンコードします (そうすれば、IPv4 アドレスをまったく同じ方法で扱うことができます)。

于 2013-07-05T02:04:38.590 に答える