我知道这个问题已被问过很多次,但我无法找到最终的解决方案;所以这里:
如何在不知道数据库的情况下,在数据库中使用最佳实践存储IP(IPv4和IPv6)?这用于数据库抽象目的,例如PHP PDO。
小调,我有PHP 5.2.17,因为我在Windows上需要PEAR。
人们一直建议将它存储为varbinary(16)并使用mysql函数inet6_ntop和inet6_pton来传递IP作为字符串来回传递;像Extending MySQL 5 with IPv6 functions建议的那样。在PHP中,函数inet_pton()和inet_ntop()可以在ThiefMaster中将IPv4和IPv6来回转换为二进制格式this question is suggesting,但是不清楚如何将二进制内容传递给SQL INSERT / UPDATE字符串(这些php函数仅与php 5.3.0 on windows一起提供,即使可以对它们进行反向工程)。我真的很喜欢Jake所做的事情和his results with regards to integer representations of IPs in DBs,如果我要将这个实现到我的数据库中,这可能会在一些遥远的,无法预料的未来派上用场,但后来我对数据库不确定使用PHP PDO进行数据库抽象的交叉兼容性。 This post似乎提供了关于存储二进制值的一个接近的答案,但是不能将未转义的二进制注入字符串作为潜在的危险吗?另外,如果您遵循这条路线,如果某些开发人员想要快速查找,有多少DB可以将varbinary(16)/ int(128bit)转换为代表性IP?
在我看来,最简单的方法是将ip string as-is插入varchar(45)。但是那些想要使用inet_ntop()和inet_pton()函数在PHP(逆向工程as djmaze(AT)dragonflycms(.)org或MagicalTux at FF dot st建议)中遵循复杂路径的人,如何存储和检索IPv6为二进制?有人可以使用来自<?php $strIP = "2001:4860:b002::68"; ?>
的PDO,使用INSERT然后使用SELECT预处理语句来提供示例吗?
正如你所看到的,我已经完成了我的研究,但这个IPv6的终极良好实践对我来说并不清楚。
答案 0 :(得分:2)
与您的研究表明一样,将IP地址存储为规范形式的字符串,二进制字符串或整数是有好处和问题的。也许存在将IP地址存储在数据库中的中间地带。
如何将它们存储为字符串,但扩展到完整的最大长度。这样你仍然可以比较它们(==,&gt;,&lt;等等),但它们仍然可读,你不需要特殊字符的特殊输入和输出编码。
如何执行此操作的示例:
function expand_ip_address($addr_str) {
/* First convert to binary, which also does syntax checking */
$addr_bin = @inet_pton($addr_str);
if ($addr_bin === FALSE) {
return FALSE;
}
/* Then differentiate between IPv4 and IPv6 */
if (strlen($addr_bin) == 4) {
/* IPv4: print each byte as 3 digits and add dots between them */
return implode('.', array_map(
create_function('$byte', 'return sprintf("%03d", ord($byte));'),
str_split($addr_bin)
));
} else {
/* IPv6: print as hex and add colons between each group of 4 hex digits */
return implode(':', str_split(bin2hex($addr_bin), 4));
}
}
还有一些例子:
/* Test IPv4 */
var_dump(expand_ip_address('192.0.2.55'));
/* Test IPv6 */
var_dump(expand_ip_address('2001:db8::abc'));
/* Test invalid */
var_dump(expand_ip_address('192:0:2:55'));
哪种产品:
string(15) "192.000.002.055"
string(39) "2001:0db8:0000:0000:0000:0000:0000:0abc"
bool(false)