仅当数据库中存在包含IP地址的行时,我才在尝试将MikroTik IP记帐数据导入MySQL的脚本。
我有一个表services
,其中有列id
(服务ID)和ipv4
(服务IP地址),其中包含要存储其会计数据的IP地址行。
然后我有另一个表traffic_counters
,其中包含列id
,service_id
,download_bytes
,upload_bytes
和date
当前,当从API提取会计数据时,如果我使用print_r($ARRAY)
,则会得到如下输出:
Array ( [0] => Array ( [.id] => *0 [src-address] => 10.2.1.2 [dst-address] => 10.1.1.20 [packets] => 4 [bytes] => 4528 ) [1] => Array ( [.id] => *1 [src-address] => 10.1.1.20 [dst-address] => 18.196.198.94 [packets] => 2 [bytes] => 80 ) [2] => Array ( [.id] => *2 [src-address] => 10.2.1.2 [dst-address] => 10.100.1.1 [packets] => 16 [bytes] => 2216 )
我只是在此阶段想要跟踪IP地址和传输的字节。我曾经使用过一个脚本,该脚本将所有会计数据保存到一个表中,然后将其分类到一个新表中,然后在完成时清除,但是此过程花费的时间过长,有时该脚本可以运行两个小时,然后再输入所有数据临时放入表中。
我之前的查询是
SELECT
ip_address,
SUM(upload_bytes) as upload_bytes,
SUM(download_bytes) as download_bytes,
SUM(upload_bytes + download_bytes) as total_bytes,
timeanddate
FROM
(
(
SELECT
ip_accounting.src_address as ip_address,
SUM(ip_accounting.bytes) AS upload_bytes,
0 as download_bytes,
ip_accounting.accounting_router_ip,
ip_accounting.accounting_router_id,
timeanddate
FROM
ip_accounting
GROUP BY
src_address
)
UNION ALL
(
SELECT
ip_accounting.dst_address as ip_address,
0 AS upload_bytes,
SUM(ip_accounting.bytes) as download_bytes,
ip_accounting.accounting_router_ip,
ip_accounting.accounting_router_id,
timeanddate
FROM
ip_accounting
GROUP BY
dst_address
)
) a
GROUP BY
ip_address,
YEAR(timeanddate),
MONTH(timeanddate),
DAY(timeanddate)
ORDER BY
ip_address
因此基本上将源IP作为上传IP,将目标IP作为下载
我需要更改脚本以像开头提到的那样通过API来获取所有数据,并通过foreach循环运行它以查找services.ipv4
表/列中的匹配IP地址,然后插入/将其更新到traffic_counters
表
我在如何在这种类型的数组输出上使用foreach命令时遇到了一个问题,并且不确定如何编写脚本的顺序。
我当前的脚本执行每日记帐,该记帐必须保持不变,例如每次IP记帐更新都会将字节添加到现有的traffic_counters
表中,如果日期不是当前日期,则会插入新行。
到目前为止,我已经尝试过
$API->write('/ip/accounting/snapshot/take',true);
$READ = $API->read(false);
$ARRAY = $API->parseResponse($READ);
$API->write('/ip/accounting/snapshot/print',true);
$READ = $API->read(false);
$ARRAY = $API->parseResponse($READ);
foreach($ARRAY['0']['.id'] as $ACCOUNTING) {
$id = $ARRAY['0']['.id'];
$ip_src = $ARRAY['0']['src-address'];
$ip_dst = $ARRAY['0']['dst-address'];
$bytes = $ARRAY['0']['dst-address'];
}
但是我越来越
Warning: Invalid argument supplied for foreach() in /opt/WispManager/html/admin/test.php on line 24
有人可以帮我找出最有效的方法吗,因为我在整个过程中都花了我的时间,所以我不想在mysql中存储任何临时数据。
我正在尝试复制Splnyx进行IP记帐的方式。
编辑: 我玩了一些,弄清楚了如何使用数组进行foreach循环,并按我的要求完成了所有工作。我只是不确定我的操作方式是否非常有效,如果有一个更简单/更快速的解决方案,也许有人可以帮我检查一下我的代码并为我指出正确的方向。
我的新脚本:
<?php
//Require admin
require_once("inc/admin.php");
require_once ("../includes/routeros_api.class.php");
//SET
$ip = "10.100.1.1";
//Connect to MikroTik API
$API = new RouterosAPI();
$API->debug = $config['api']['debug'];
if (!$API->connect($ip, $config['api']['username'], $config['api']['password'])) {
echo "Could not connect to RouterOS API";
} else {
$API->write('/ip/accounting/snapshot/take',true);
$READ = $API->read(false);
$ARRAY = $API->parseResponse($READ);
$API->write('/ip/accounting/snapshot/print',true);
$READ = $API->read(false);
$ARRAY = $API->parseResponse($READ);
foreach($ARRAY as $ACCOUNTING) {
$ip_src = $ACCOUNTING['src-address'];
$ip_dst = $ACCOUNTING['dst-address'];
$bytes = $ACCOUNTING['bytes'];
//Check if ip in use UPLOAD
$query = "SELECT id, ipv4 FROM services WHERE ipv4='$ip_src' AND deleted !='1'";
$result = mysqli_query($conn, $query);
$row = mysqli_fetch_array($result);
if(mysqli_num_rows($result) > 0) {
$service_id = $row['id'];
//Update Download Traffic
$check_if_exist_query = "SELECT * FROM traffic_counters WHERE service_id='$service_id' AND date=CURRENT_DATE()";
$check_result = mysqli_query($conn, $check_if_exist_query);
$check_num_rows = mysqli_num_rows($check_result);
if($check_num_rows == 0) {
$add_query = "INSERT INTO traffic_counters (service_id, upload_bytes, date) VALUES ('$service_id', '$bytes', CURRENT_DATE());";
$add_result = mysqli_query($conn, $add_query);
} else {
$update_query = "UPDATE traffic_counters SET
upload_bytes = upload_bytes + $bytes
WHERE service_id='$service_id' AND date=CURRENT_DATE();
";
$update_result = mysqli_query($conn, $update_query);
}
}
//Check if ip in use DOWNLOAD
$query = "SELECT id, ipv4 FROM services WHERE ipv4='$ip_dst' AND deleted !='1'";
$result = mysqli_query($conn, $query);
$row = mysqli_fetch_array($result);
if(mysqli_num_rows($result) > 0) {
$service_id = $row['id'];
//Update Download Traffic
$check_if_exist_query = "SELECT * FROM traffic_counters WHERE service_id='$service_id' AND date=CURRENT_DATE()";
$check_result = mysqli_query($conn, $check_if_exist_query);
$check_num_rows = mysqli_num_rows($check_result);
if($check_num_rows == 0) {
$add_query = "INSERT INTO traffic_counters (service_id, download_bytes, date) VALUES ('$service_id', '$bytes', CURRENT_DATE());";
$add_result = mysqli_query($conn, $add_query);
} else {
$update_query = "UPDATE traffic_counters SET
download_bytes = download_bytes + $bytes
WHERE service_id='$service_id' AND date=CURRENT_DATE();
";
$update_result = mysqli_query($conn, $update_query);
}
}
}
$API->disconnect();
}
?>