PHP 的 ip2long 函数默认不支持 IPv6,其实只要简单的修改即可支持。
因
在很多项目中需要将 IP 地址存储于数据库中,因地址格式复杂,存储可能导致出现格式等兼容性问题,因此一般都会对地址进行处理。在 PHP 中一般使用 ip2long 函数将地址转换为一个长数组,但是需要注意的是此函数目前仅仅支持 IPv4 类的地址。
启
在谷歌中搜索后发现在 PHP 官网中存在一个大佬的解决方案
Here some working ip2long6 and long2ip6 functions - keep in mind that this needs php gmp-lib.
这是一个可以使用的 IPv6 转换方法 - 需要注意的是此方法需要使用 PHP 的 gmp-lib 库/扩展。
此为试验的 Demo 。
<?php
$ipv6 = "2001:4860:a005::68";
function ip2long6($ipv6) {
$ip_n = inet_pton($ipv6);
$bits = 15; // 16 x 8 bit = 128bit
while ($bits >= 0) {
$bin = sprintf("%08b",(ord($ip_n[$bits])));
$ipv6long = $bin.$ipv6long;
$bits--;
}
return gmp_strval(gmp_init($ipv6long,2),10);
}
function long2ip6($ipv6long) {
$bin = gmp_strval(gmp_init($ipv6long,10),2);
if (strlen($bin) < 128) {
$pad = 128 - strlen($bin);
for ($i = 1; $i <= $pad; $i++) {
$bin = "0".$bin;
}
}
$bits = 0;
while ($bits <= 7) {
$bin_part = substr($bin,($bits*16),16);
$ipv6 .= dechex(bindec($bin_part)).":";
$bits++;
}
// compress
return inet_ntop(inet_pton(substr($ipv6,0,-1)));
}
print $ipv6long = ip2long6($ipv6)."\n";
print $ipv6 = long2ip6($ipv6long)."\n";
?>
outputs:
42541956150894553250710573749450571880
2001:4860:a005::68
注意:因 IPv6 地址转换后的字符串长度增加,因此可能需要调整数据库的字段长度(38位)。
止
实际上此函数的使用是因为魔改大佬的 Access 项目所用到的,这是 @kokororin 大佬的作品,在此基础上进行了一系列改动:
- 废弃了老旧的本地数据库,改为使用在线接口进行地址解析(速度有所下降但是准确率有很大提高)
- 更新了一些组件的版本及清理掉了部分冗余文件
- 添加了更多的浏览器检测代码(Chromium 版 Edge 、新版 Opera、QQ浏览器 等等)
- 支持了 IPv6 地址解析存储(暂不支持地址解析所在地)
更多使用说明及特性请转至 GitHub 查看
小贴士:因改动较大,因此若尝试这些新特性请使用mainline
分支,master
分支为小修改分支。
附录
参考链接
本文由 柒 创作,采用 知识共享署名4.0
国际许可协议进行许可。
转载本站文章前请注明出处,文章作者保留所有权限。
最后编辑时间: 2019-12-26 15:48 PM
这是用来做什么的