很多时候,我们需要做 IP 黑名单或者 IP 白名单,来对访客进行限制,很常见的一种就是对同一 IP 段内的所有 IP 进行允许或限制,那么就我们就需要知道访客 IP 是否属于该 IP 段范围内。本文仅记录一下方法。
其实本文还有一个应用场景,就是通常存储在数据库中的 IP 地址都是 varchar 类型的,而如果采用 INT 类型来保存 IP ,则可以对数据库起到优化的作用,当然这里只是针对 IP4 进行讲解。
判断一个 IP 是否属于某一个 IP 段,思路就是将 IP 转换成 int 类型的数值,然后进行比较。而在 PHP 中内置了 ip 和数值的互换的函数:ip2long($ip_addr) 和 long2ip($long)。
ip2long($ip_addr)中若 $ip_addr 不是有效的 IP 地址,则会返回 false,若是有效的 IP 地址,则会将其转换为有符号 long 类型,而有些时候 IP 地址转换后可能会超出有符号的 long 长度,这样会导致出现负数。
long 类型是 4 个字节的,其有符号范围是:2147483647 ~ -2147483648,无符号的范围是:4294967295 ~ 0
而最大的 IP4 地址是:255.255.255.255,对应的数值是:4294967295,所以可以将其转成无符号的数值。2147483647 数值对应的 IP 为:127.255.255.255,
long2ip(2147483647)所以 IP 地址在 0.0.0.0 至 127.255.255.255 范围内的不会出现负数,而在 128.0.0.0 至 255.255.255.255 范围内的会出现负数情况。
以下代码给出了一个完整、正确的判断指定 IP 是否属于某 IP 段内的小例子。
$start_ip = "42.236.184.1"; $end_ip = "42.236.184.255"; $ip = "42.236.184.128"; check_ip($ip,$start_ip,$end_ip); function check_ip($ip,$start_ip,$end_ip) { $ip = get_ip2long($ip); $start_ip = get_ip2long($start_ip); $end_ip = get_ip2long($end_ip); if($ip >= $start_ip && $ip <= $end_ip) { return true; } return false; } // decbin() 十进制转二进制 // bindec() 二进制转十进制。函数将一个二进制数转换成 integer。可转换的最大的数为 31 位 1 或者说十进制的 2147483647。PHP 4.1.0 开始,该函数可以处理大数值,这种情况下,它会返回 float 类型。 function get_ip2long($ip) { return bindec(decbin(ip2long($ip))); //方法二:return sprintf('%u',ip2long($ip)); //%u:不包含正负号的十进制数 }
更多PHP相关知识,请访问PHP中文网!
以上是PHP判断某个IP4是否属于某一个IP段的详细内容。更多信息请关注PHP中文网其他相关文章!