我想将 IP 地址与用户注册、帖子、上传等一起存储。我以前创建的网站一直使用ip2long/long2ip
并将其存储UNSIGNED INT
为 IPv4 是我唯一关心的问题。所以我会通过 运行 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 地址一切正常,但$ipAddressDB
IPv6 地址&(diamond-with-question-mark)(diamond-with-question-mark)Q
在我使用2607:f0d0:1002:0051:0000:0000:0000:0004
测试 IP 时返回值,我真的不知道为什么?我用inet_pton
错了吗?我必须添加一些东西吗?是因为测试IPv6地址吗?
我假设一旦我开始工作,因为我们需要存储在 2 列中,我为数据库 IP 创建 2 个变量,如果它是 IPv4,我将它分配给变量 1 并将变量 2 留空。然后,如果是 IPv6,我将其拆分,将前半部分放入变量 1,将第二部分放入变量 2。然后在插入/选择时,如果第二列为空,我们可以假设它是 IPv4 地址吗?
我什至不能 100% 确定我正在尝试做的事情是否真的可行?如果不是,最好只采用 IPv6 地址(不带inet_pton
),然后以这种方式拆分它们吗?