Одна переменная вместо нескольких

По поводу моего другого вопроса Перенос учета IP в одну строку таблицы
Я использовал ip2long и long2ip для преобразования туда-сюда … Есть ли способ, которым я могу указать диапазон следующим образом: $ iprange = «192.168.0.1-192.168.255.254»; вместо $ iprangestart = «192.168.0.1»; $ iprangeend = «192.168.255.254»; а также иметь возможность указывать несколько диапазонов, разделенных запятой в одной переменной, например: $ ipranges = «192.168.0.1-192.168.255.254,10.0.0.1-10.255.255.254»;

Или даже, если возможно, укажите диапазон с нотацией CIDR, например:
$ iprange = «192.168.0.0/16, 10.0.0.0/8»;

IP для длинных и длинных для IP-кода:

include ("config.php");
$conn = mysqli_connect($SQLserver, $SQLusername, $SQLpassword, $SQLdatabase);
if (!$conn) {
die("Could not connect: " . mysqli_connect_error());
}
$IP = "192.168.0.1";
$IPEND = "192.168.255.254";

$NOTIP = "192.168.0.1";
$NOTIPEND = "192.168.255.254";$IP = ip2long($IP);
$IPEND = ip2long($IPEND);
$NOTIP = ip2long($NOTIP);
$NOTIPEND = ip2long($NOTIPEND);
$query = "SELECT * , SUM(bytes) AS total_bytes FROM ipaccountingtest WHERE src_address BETWEEN $IP AND $IPEND AND NOT dst_address BETWEEN $NOTIP AND $NOTIPEND GROUP BY src_address";$result = mysqli_query($conn,$query);echo "<table>";
echo "<tr><th>src_address</th><th>Bytes</th></tr>";

while($row = mysqli_fetch_array($result)) {
if (isset($row['src_address'])) {
$src_address = $row['src_address'];
$src_address = long2ip($src_address);
}
/*if (isset($row['dst_address'])) {
$dst_address = $row['dst_address'];
} */
if (isset($row['total_bytes'])) {
$bytes = $row['total_bytes'];
}

echo "<tr><td>".$src_address."</td><td>".$bytes."</td></tr>";
}

echo "</table>";
mysqli_close($conn);
?>

Также вместо того, чтобы иметь диапазон IP в документе, я хотел бы вставить его в SQL, я добавил таблицу в свою базу данных следующим образом

Table name: accountingipranges

column1 id

column2 iprangestart

column3 iprangeend

Как я могу заставить свой сценарий извлечь это из базы данных и затем отобразить его так же, как я делал раньше, но вместо того, чтобы иметь диапазон IP в сценарии и заставить его запрашивать базу данных?

Как я могу получить его для вывода таблицы следующим образом:

IP-адрес | СКАЧАТЬ | ЗАГРУЗИТЬ | ВСЕГО

Пример:

IP ADDRESS | DOWNLOAD | UPLOAD | TOTAL
192.168.2.3  1024       1024     2046

Мне нужно, чтобы скрипт исключал свой учет подсетей, например, он не должен учитывать трафик в и из диапазонов, указанных в таблице excludeaccountingipranges.

Таблица excludeaccountingipranges также выглядит как таблица accountingipranges
например:

Table name: excludeaccountingipranges

column1 id

column2 iprangestart

column3 iprangeend

0

Решение

Я бы положил ваши диапазоны в массив. Таким образом, вы можете указать любые диапазоны и столько, сколько захотите. Что-то вроде этого:

$ranges = array(
array(
'start' => '192.168.0.1',
'end'   => '192.168.255.254'
),
array(
'start' => '10.0.0.1',
'end'   => '10.255.255.254'
)
)

Тогда используйте foreach() цикл, чтобы пройти их и построить запрос SQL:

$wheres = array();

foreach ( $ranges as $range ) {
$where[] = '( src_address BETWEEN ' . ip2long( $range['start'] ) . ' AND ' . ip2long( $range['end'] ) . ' )';
}

Затем завершите ваш запрос следующим образом:

$query = "SELECT *, SUM( bytes ) AS total_bytes
FROM ipaccountingtest
WHERE ( " . implode( ' OR ', $wheres ) . " )
GROUP BY src_address";

Так вот что все это делает:

  • Помещает все ваши диапазоны IP в массив.
  • Прокручивает массив для построения предложения WHERE.
  • Создает ваш запрос, помещая предложение WHERE на место, разделяя каждый диапазон IP OR так что он возвращает данные, связанные со всеми указанными диапазонами IP.

С указанными выше диапазонами IP и циклом, вот как будет выглядеть окончательный запрос:

SELECT *, SUM( bytes ) AS total_bytes
FROM ipaccountingtest
WHERE (( src_address BETWEEN 3232235521 AND 3232301054 ) OR ( src_address BETWEEN 167772161 AND 184549374 ))
GROUP BY src_address

Обратите внимание, что я не проверял ни один из приведенных выше кодов .. могут быть синтаксические ошибки в нем или что-то подобное. Тем не менее, идея здесь заключалась в том, чтобы передать метод, с помощью которого вы можете достичь того, что вы хотите. Если вы обнаружите здесь ошибки, вы можете предоставить подробную информацию о них, и я посмотрю, что я могу сделать, чтобы помочь в их устранении. Но метод должен быть надежным, и любые ошибки должны быть простыми для исправления.

0

Другие решения

Я выяснил, для создания функции для того, что я хотел сделать

function cidrToRange($ranges) {
if(!empty($ranges)) {
$ranges = str_replace(" ", "", $ranges);
$ranges_array = explode(',', $ranges);foreach($ranges_array as $ip_and_cidr) {
$cidr = explode('/', $ip_and_cidr);
$range['start'] = long2ip((ip2long($cidr[0])) & ((-1 << (32 - (int)$cidr[1]))));
$range['end'] = long2ip((ip2long($range['start'])) + pow(2, (32 - (int)$cidr[1])) - 1);
if(!isset($ip_ranges)) {
$ip_ranges = array($range);
} else {
$ip_ranges = array_merge($ip_ranges, array($range));
}
//print_r($ip_ranges);
}
return($ip_ranges);
} else {
return(false);
}
}
0

По вопросам рекламы [email protected]