您不必在 PHP 中处理这个问题,这就是 MySQL 原生函数的用途。看这个例子:
create table iptable (
ip int(32) unsigned not null,
comment varchar(32) not null
);
insert into iptable (ip, comment) values (inet_aton('10.0.0.3'), 'This is 10.0.0.3');
select * from iptable;
+-----------+------------------+
| ip | comment |
+-----------+------------------+
| 167772163 | This is 10.0.0.3 |
+-----------+------------------+
select inet_ntoa(ip) as ip, comment from iptable;
+----------+------------------+
| ip | comment |
+----------+------------------+
| 10.0.0.3 | This is 10.0.0.3 |
+----------+------------------+
如果你想在同一个字段中同时处理 ipv4 和 ipv6,并且你使用的是 Mysql 5.6 或更高版本,你可以使用 varbinary(16) 以及函数 inet6_aton 和 inet6_ntoa。这是一个更好的例子,说明为什么应该使用 MySQL 函数而不是在 PHP 中处理二进制数据:
create table iptable2 (
ip varbinary(16) not null,
comment varchar(32) not null
);
insert into iptable2 (ip, comment) values
(inet6_aton('192.168.1.254'), 'This is router 192.168.1.254'),
(inet6_aton('::1'), 'This is ipv6 localhost ::1'),
(inet6_aton('FE80:0000:0000:0000:0202:B3FF:FE1E:8329'), 'This is some large ipv6 example')
;
select * from iptable2;
+------------------+---------------------------------+
| ip | comment |
+------------------+---------------------------------+
| +¿?¦ | This is router 192.168.1.254 |
| ? | This is ipv6 localhost ::1 |
| ¦Ç ??¦ ¦?â) | This is some large ipv6 example |
+------------------+---------------------------------+
select inet6_ntoa(ip) as ip, comment from iptable2;
+--------------------------+---------------------------------+
| ip | comment |
+--------------------------+---------------------------------+
| 192.168.1.254 | This is router 192.168.1.254 |
| ::1 | This is ipv6 localhost ::1 |
| fe80::202:b3ff:fe1e:8329 | This is some large ipv6 example |
+--------------------------+---------------------------------+
您可以看到,通过这样做,您实际上可以避免评估不同格式的 ipv6 地址,因为 MySQL 会将它们转换为二进制并返回到最简单的表达式。
我知道这个问题已经有 2 年多了,但我想让这些信息对遇到的其他人有用。
HTH
弗朗西斯科·萨拉博佐