编辑:通过PHP API的MikroTik IP记帐仅存储数据库中指定的信息

时间:2018-08-02 13:08:48

标签: php mysql api mikrotik

仅当数据库中存在包含IP地址的行时,我才在尝试将MikroTik IP记帐数据导入MySQL的脚本。

我有一个表services,其中有列id(服务ID)和ipv4(服务IP地址),其中包含要存储其会计数据的IP地址行。

然后我有另一个表traffic_counters,其中包含列idservice_iddownload_bytesupload_bytesdate

当前,当从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();
}
?>

0 个答案:

没有答案