说明:

检测一个IP地址是否在规定网段内的类。IP在指定IP段范围内的话返回TRUE和信息“IP检测通过”,IP不在IP段范围内则返回FALSE和错误信息,错误信息可以从属性“msg”中获得,详见用法和代码。

代码:


<?php
/**
* 说明:检测IP是否在IP段内
* 作者:upall
*/
class ipCheck {
public $ipRangeStr = '10.0.0.1/8';
public $msg = '';

function __construct($ipRangeStr){
  !empty($ipRangeStr) ? $this->ipRangeStr = $ipRangeStr : '';
}

function check($ip = '') {
  empty($ip) && $ip = $this->getClientIp();
 
  # 判断检测类型
  if (FALSE !== strpos($this->ipRangeStr,'-')){
   $type = 'size'; // 简单比大小:10.0.0.1-254 OR 10.0.0.1-10.0.0.254
  }else if(FALSE !== strpos($this->ipRangeStr,'/')){
   $type = 'mask'; // 掩码比大小:10.0.0.1/24
  }else{
   $this->msg = '错误的IP范围值';
   return FALSE;
  }
  # 分析IP范围
  if ('size' === $type){
   $ipRangeStr = explode('-',$this->ipRangeStr);
   $ipAllowStart = $ipRangeStr[0];
   $ipAllowEnd = $ipRangeStr[1];
   if (FALSE === strpos($ipAllowEnd,'.')){ # 10.0.0.254 OR 254
    $ipAllowElmArray = explode('.',$ipAllowStart);
    $ipAllowEnd = $ipAllowElmArray[0] . '.' .
         $ipAllowElmArray[1] . '.' .
         $ipAllowElmArray[2] . '.' .
         $ipAllowEnd;
   }
  }else if ('mask' === $type){
   $ipRangeStr = explode('/',$this->ipRangeStr);
   $ipRangeIP = $ipRangeStr[0];
   # 获取掩码中最后一位非零数的值
   $ipRangeMask = (int)$ipRangeStr[1];
   $maskElmNumber = floor($ipRangeMask/8); # 保留IP前几段
   $maskElmLastLen = $ipRangeMask % 8; # 255.255.here.0
   $maskElmLast = str_repeat(1,8-$maskElmLastLen);
   $maskElmLast = bindec($maskElmLast); # 掩码中IP末段最大值(十进制)
  
   // 获取IP段开始、结束值
   $ipRangeIPElmArray = explode('.',$ipRangeIP);
   if (0 == $maskElmNumber){
    $ipAllowStart = '0.0.0.0';
    $ipAllowEnd = $maskElmLast . '.254.254.254';
   }else if (1 == $maskElmNumber){
    $ipAllowStart = $ipRangeIPElmArray[0] . '.' . '0.0.0';
    $ipAllowEnd = $ipRangeIPElmArray[0] . '.' . $maskElmLast . '.254.254';
   }else if (2 == $maskElmNumber){
    $ipAllowStart = $ipRangeIPElmArray[0] . '.' . $ipRangeIPElmArray[1] . '.' . '0.0';
    $ipAllowEnd = $ipRangeIPElmArray[0] . '.' . $ipRangeIPElmArray[1] . '.' . $maskElmLast . '.254';
   }else if (3 == $maskElmNumber){
    $ipAllowStart = $ipRangeIPElmArray[0] . '.' . $ipRangeIPElmArray[1] . '.' . $ipRangeIPElmArray[2] . '.' . '0';
    $ipAllowEnd = $ipRangeIPElmArray[0] . '.' . $ipRangeIPElmArray[1] . '.' . $ipRangeIPElmArray[2] . '.' . $maskElmLast;
   }else if (4 == $maskElmNumber){
    $ipAllowEnd = $ipAllowStart = $ipRangeIP;
   }else{
    $this->msg = '错误的IP段数据';
    return $this->msg;
   }
  }else{
   $this->msg = '错误的IP段类型';
   return $this->msg;
  }
  // 检测IP
  $ipAllowStart = $this->getDecIp($ipAllowStart);
  $ipAllowEnd = $this->getDecIp($ipAllowEnd);
  $ip = $this->getDecIp($ip);
  if (!empty($ip)){
   if ($ip <= $ipAllowEnd && $ip >= $ipAllowStart){
    $this->msg = 'IP检测通过';
    return TRUE;
   }else{
    $this->msg = '此为被限制IP';
    return FALSE;
   }
  }else{
   FALSE === ($this->msg) && $this->msg == '没有提供待检测IP'; // getClentIp() 是否返回false
   return $this->msg; // 没有获取到客户端IP,返回
  }
}

// 10进制IP
function getDecIp($ip){
  $ip = explode(".", $ip);
  return $ip[0]*255*255*255+$ip[1]*255*255+$ip[2]*255+$ip[3];
}

// 获取客户端IP
function getClientIp(){
  if(isset($_SERVER['REMOTE_ADDR'])){
   return $_SERVER['REMOTE_ADDR'];
  }else{
   $this->msg = '不能获取客户端IP';
   return FALSE;
  }
}
}
?>

用法:


$ipCheck = new ipCheck('192.168.1.1-192.168.1.254');
echo (TRUE === $ipCheck ->check('192.168.1.45')) ? '在范围内' : $ipCheck->msg;

 


$ipCheck = new ipCheck('192.168.1.1-254');
echo (TRUE === $ipCheck ->check('192.168.1.45')) ? '在范围内' : $ipCheck->msg;

 


$ipCheck = new ipCheck('192.168.1.1/24');
echo (TRUE === $ipCheck ->check('192.168.1.45')) ? '在范围内' : $ipCheck->msg;