私は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の作品が見つかりますが、DB内のIPを持つレコードの多くと1 IPずつ増加し、このIPがDBに存在するかどうかをチェックするには、非常に長い道のりがあります。どのように私はこのアルゴリズムを最適化できますか?未使用のIPを取得する方法はありますか?
データベース内の余分なテーブルのないよりよい解決策を見つけた、と思います利用可能なすべてのIPアドレスのテーブルを作ってから、あなたの他のテーブルに対して右の結合をして、無料のIPアドレスのリストを入手してください。 – cmorrissey
@ cmorrisseyは良い考えに感謝します。しかし、私は利用可能なIPアドレスの範囲を変更したい場合は問題になります、私は毎回新しいテーブルを作成する必要があります。また、この表は非常に大きくなります:min - 10.0.0.11 '、max - '10 .255.255.255'(16777 204 records) –
大丈夫私はあなたのために新しい考えを持っています...データベース内の行数をIPアドレスの範囲内で数えて、次の範囲に移動しない場合に使用可能なIPアドレスがあるかどうかを確認します。これにより、範囲を再帰的に絞り込むことができます。これは非常に基本的な検索機能ですが、指数関数的に検索を高速化する必要があります。 – cmorrissey