一个变量而不是多个
One variable instead of multiple
关于我的另一个问题Transfer IP accounting to single row table
我使用 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,如下所示
Table name: accountingipranges
column1 id
column2 iprangestart
column3 iprangeend
如何让我的脚本从数据库中提取它,然后以与之前相同的方式显示它,而不是在脚本中包含 IP 范围并让它查询数据库?
如何让它输出 table 如下:
IP 地址 |下载 |上传 |总计
一个例子:
IP ADDRESS | DOWNLOAD | UPLOAD | TOTAL
192.168.2.3 1024 1024 2046
我需要脚本来排除它自己的子网计费,例如,它不能计入在 excludeaccountingipranges 中指定的范围内的流量 table
excludeaccountingipranges table 也看起来像 accountingipranges table
例如:
Table name: excludeaccountingipranges
column1 id
column2 iprangestart
column3 iprangeend
我会将您的范围放入一个数组中。这样,您可以指定任何范围,数量不限。像这样:
$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 子句,用
OR
分隔每个 IP 范围,以便它 returns 与指定的所有 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
请注意,我尚未测试以上任何代码。其中可能存在语法错误或类似错误。然而,这里的想法是传达您可以用来完成您想要的事情的方法。如果您最终在此处发现错误,您可以提供有关错误的详细信息,我会看看我能做些什么来帮助解决这些错误。但是方法应该是正确的,任何错误都应该很容易修复。
我想出了为我想做的事情创建一个函数
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);
}
}
关于我的另一个问题Transfer IP accounting to single row table 我使用 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,如下所示
Table name: accountingipranges
column1 id
column2 iprangestart
column3 iprangeend
如何让我的脚本从数据库中提取它,然后以与之前相同的方式显示它,而不是在脚本中包含 IP 范围并让它查询数据库?
如何让它输出 table 如下:
IP 地址 |下载 |上传 |总计
一个例子:
IP ADDRESS | DOWNLOAD | UPLOAD | TOTAL
192.168.2.3 1024 1024 2046
我需要脚本来排除它自己的子网计费,例如,它不能计入在 excludeaccountingipranges 中指定的范围内的流量 table
excludeaccountingipranges table 也看起来像 accountingipranges table 例如:
Table name: excludeaccountingipranges
column1 id
column2 iprangestart
column3 iprangeend
我会将您的范围放入一个数组中。这样,您可以指定任何范围,数量不限。像这样:
$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 子句,用
OR
分隔每个 IP 范围,以便它 returns 与指定的所有 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
请注意,我尚未测试以上任何代码。其中可能存在语法错误或类似错误。然而,这里的想法是传达您可以用来完成您想要的事情的方法。如果您最终在此处发现错误,您可以提供有关错误的详细信息,我会看看我能做些什么来帮助解决这些错误。但是方法应该是正确的,任何错误都应该很容易修复。
我想出了为我想做的事情创建一个函数
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);
}
}