1、前言
IP转换成整型存储是数据库优化一大趋势,字符串索引比整型索引消耗资源很多,特别是表中数据量大的时候,以及求查询某一个ip段的数据。本文所指的IP是ip4,ip6暂不再讨论范围
2、ip4转化为整形
这里将介绍:
- php自带函数 ip2long
- php原生模拟ip2long的过程
2.1、ip2long
判断一个 ip4 地址是不是合法的 ip,符合则返回一个长整型,不符合返回 false
以下是测试:
然而当 ip4 值较大时,ip2long转化会出现负数的情况
2.2、php原生模拟ip2long的过程
php自带的ip2long虽然好用,由于返回值是int,所以会造成数据溢出,比如有些ip地址转换后变成负数,为了好看,还是需要自己模拟一个ip2long的过程,不多说,先上代码
function ipToInt($ip) { $newHex = ''; $aIp = explode('.', $ip); //将ip分割成数组 foreach ($aIp as $key => $value) { //十进制最大值是255,超过是不合法的ip,直接返回 if($value > 255){ return ''; } $hex = dechex($value);//将十进制转为十六进制 //每个ip段的值最大为255,十六进制为FF,故最长是两位, //例IP = 1.1.1.1 如果不补0,则十六进制为 1111,十进制为 4369 //补0为 十六进制为 01010101,十进制为 16843009 if(strlen($hex) < 2) { $hex = '0'.$hex; //如果十六进制长度小于2,则自动补0 } $newHex .= $hex; } $int = hexdec($newHex);//十六进制转为十进制 return $int; }
以下是测试:
3、将整形转化为ip
这里将介绍:
- php自带函数 long2ip
- php原生模拟long2ip的过程
long2ip 只会返回0.0.0.0 到255.255.255.255的内容,
传人空值默认返回0.0.0.0,超出最大值返回255.255.255.255
以下为测试:
long2ip可以识别由ip2long转化产生的负数(可喜可贺);所有在使用过程中,ip2long和long2ip一起使用就不会有什么问题,当然也要介绍一下如何用原生的模拟long2ip的过程
3.2、php原生模拟long2ip的过程
php自带的long2ip已经可以解决大部分问题,这里也只是简单介绍一下原生的模拟方法,不多说,先上代码
function intToIp($int) { //FFFFFF最大为4294967295 $int = $int > 4294967295 ? 4294967295 : $int; $dec = dechex($int); //讲十进制转为十六进制 //十六进制默认会忽略最左边的0,毕竟是0了,怎么算都是0,留着也没用 //但中间的0会保留,而IP的十六进制最大为FFFFFF(大F团) //所有为防止7位IP的出现,我们只能手动补0,才能成双成对(2个一对) if(strlen($dec) < 8) { $dec = '0'.$dec; //如果长度小于8,最自动补0 } for($i = 0; $i < 8; $i += 2){ $hex = substr($dec, $i, 2); $ippart = substr($hex, 0, 1);//截取十六进制的第一位 if($ippart === '0') { $hex = substr($hex, 1, 1);//如果第一位为0,说明原始数值只有1位,还是要拆散 } $aIp[] = hexdec($hex); //将每段十六进制数转换我为十进制,即每个ip段的值 } return implode('.',$aIp); }
4.1、ip2long
判断一个 ip4 地址是不是合法的 ip,符合则返回一个长整型,不符合返回 false
详情参考:http://php.net/manual/en/function.ip2long.php
4.2、dechex
十进制转化为十六进制(不用自己写方法,爽)
详情参考:http://www.php.net/manual/zh/function.dechex.php
4.3、hexdec
十六进制转十进制
详情参考:http://php.net/manual/zh/function.hexdec.php
4.4、long2ip
将长整型转化为 ip4 格式的字符串,用于判断一个ip是否合法
详情参考:http://php.net/manual/en/function.long2ip.php