php - 获取免费IP地址的算法

标签 php mysql algorithm optimization yii2

我使用 yii2。我需要通过 getFreeIPAddress 方法找到未使用(不在数据库中)的 IP。我有这样的类(class):

class Radreply extends ActiveRecord {

   const ATTRIBUTE_DEFAULT_IP_ADDRESS = 'Framed-IP-Address';

   const IP_ADDRESS_MAX = '10.255.255.255';  // max value for IP 
   const IP_ADDRESS_MIN = '10.0.0.11';       // min value for IP

   public function getIntegerIP(){  // converts IP from string to integer format
       return ip2long($this->value);
   }

   public static function getFreeIPAddress(){
        $records = self::findAll(['attribute'=>self::ATTRIBUTE_DEFAULT_IP_ADDRESS]); // get all record which contain IP address
        $existIPs = ArrayHelper::getColumn($records,'integerIP'); // get array of IP which is converted to integer by method getIntegerIP

        for ($integerIP = ip2long(self::IP_ADDRESS_MIN); $integerIP<=ip2long(self::IP_ADDRESS_MAX); $integerIP++){
        // increasing one by one IP address in integer format from value IP_ADDRESS_MIN to value IP_ADDRESS_MAX

            if (!in_array($integerIP, $existIPs)){
                $stringIP = long2ip($integerIP);
                $arrayDigits = explode('.', $stringIP);
                $lastDigit = array_pop($arrayDigits);

                if ($lastDigit!='0'){ // check if last digit of IP is not 0
                    return $stringIP;
                }

            }

        }
        return '';
    }
}

方法 getFreeIPAddress 可以找到,但是在 db 中有很多带有 IP 的记录并且 IP 一个一个地增加并且检查这个 IP 是否存在于 db 中是很长的路要走。我如何优化这个算法?有没有更快的方法来获得未使用的IP?

最佳答案

我想,我找到了更好的解决方案,不需要在数据库中添加额外的表

class Radreply extends ActiveRecord {

  const ATTRIBUTE_DEFAULT_IP_ADDRESS = 'Framed-IP-Address';

  const IP_ADDRESS_MAX = '10.255.255.255';  // max value for IP 
  const IP_ADDRESS_MIN = '10.0.0.11';       // min value for IP

  public function getIntegerIP(){  // converts IP from string to integer format
      return ip2long($this->value);
  }

    public static function getFreeIPAddress(){
        $records = self::findAll(['attribute'=>self::ATTRIBUTE_DEFAULT_IP_ADDRESS]); // gets all record which contain IP address
        $existIPs = ArrayHelper::getColumn($records,'integerIP'); // gets array of IP which is converted to integer by method getIntegerIP

        $intIpAddressMin = ip2long(self::IP_ADDRESS_MIN);     // gets min IP in integer format
        $endRange = empty($existIPs) ? $intIpAddressMin : max($existIPs);  // checks if at least one IP is used
        $availableIPs = range( $intIpAddressMin, $endRange + 2);   // generates array with available IP addresses (+2 because next address can be with last digit 0)
        $missingIPs = array_diff($availableIPs,$existIPs);  // removes all used IP

        foreach ($missingIPs as $value){
            $lastDigit = $value % 256;
            if ($lastDigit != 0){
                return long2ip($value);
            }
        }
        return '';
    }
}

关于php - 获取免费IP地址的算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43397109/

相关文章:

php - Symfony2 : Where/how I can trigger my own annotation-reader?

php - 正则表达式从文本文件中删除一些行

javascript - 绘制温度的平均值

php - 如何使用codeigniter事件记录在mysql表的单个字段中搜索多个值?

algorithm - 大数字,通用算法?

php mysql 我需要一次读取一条记录直到结束

javascript - Krajee Bootstrap 文件输入,捕获 AJAX 成功响应

mysql - 如何按连接表的行(而不是列)中的值对 mysql 查询结果进行排序?

c - 如何在 C 中定义数组

MySQL - 索引会加速我的搜索查询吗?