我使用yii2。我需要通过方法getFreeIPAddress找到未使用的IP(不在数据库中)。我上课是这样的:获取免费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]); // 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作品找到,但在数据库有很多与IP记录,并通过一个IP增加一个,如果这个IP数据库中检查存在很长的路要走。我如何优化这个算法?有没有更快的方式来获得未使用的IP?
ummmm你可以创建一个所有可用IP地址的表格,然后右对齐其他表格以获得免费IP地址列表 – cmorrissey
@cmorrissey谢谢你的好主意。但是如果我想更改可用IP地址的范围,将会出现问题,我将需要每次创建新表。此表格将会非常大:min - 10.0.0.11',max - '10 .255.255.255'(16 777 204 records) –
好吧我有一个新的想法给你...请计算您的数据库在一系列IP地址之间的行数,以查看是否存在可用的IP地址(如果不到下一个范围),并且可以递归缩小范围。这是一个非常基本的搜索功能,但它应该可以加速您的搜索速度。 – cmorrissey