首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >存储在数据库中的PHP IPv4和IPv6函数

存储在数据库中的PHP IPv4和IPv6函数
EN

Stack Overflow用户
提问于 2013-07-05 09:44:44
回答 1查看 1.4K关注 0票数 1

我想存储IP地址与用户注册,帖子,上传等。以前我做的网站,我总是使用ip2long/long2ip,并将其存储为UNSIGNED INT,因为IPv4是我唯一关心的问题。因此,我将通过ip2long运行IP地址,并存储它,当我检索它时,使用long2ip。但现在我想确保它是更多的未来证据,并同时处理IPv4和IPv6。

这是我到目前为止想出的同时处理IPv4和IPv6的函数:

代码语言:javascript
复制
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地址的$ipAddressDB在我使用2607:f0d0:1002:0051:0000:0000:0000:0004测试IP时返回值&(diamond-with-question-mark)(diamond-with-question-mark)Q,我真的不知道为什么?我是不是用错了inet_pton?我需要加点什么吗?是因为测试的IPv6地址吗?

我假设一旦我开始工作了,因为我们需要存储在2列中,我为数据库IP创建了2个变量,如果它是IPv4,我将它赋值给变量1,并将变量2留空。然后如果它是IPv6,我拆分它,把前半部分放在变量1中,把第二部分放在变量2中,然后在插入/选择时,如果第二列是空的,我们可以假设它是一个IPv4地址?

我甚至不能百分之百确定我正在尝试做的事情是否真的可行?如果不是,那么直接接受IPv6地址(没有inet_pton),并以这种方式拆分它们是不是更好?

EN

回答 1

Stack Overflow用户

发布于 2013-07-05 10:04:39

您正在查看二进制形式的地址。"&“是UTF-8 0x26,0xf0和0xd0是无效的UTF-8 (显示为"�"),"Q”是UTF-8 0x51,其他字节显示为空。在存储之前将字节字符串编码为十六进制(然后您可以完全以同样的方式处理IPv4地址)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17480011

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档