php - 比较来自 MySQL 表和日志文件的数据

标签 php mysql

我的场景如下:我有一个函数可以解析一个日志文件(超过 2000 行)并在 MySQL 中存储一个表。

表格格式如下(行):id,name,realaddress,virtualaddress,bytessent,bytesreceived,time,blockedstatus。通过用户交互更改哪个“blockedstatus”并保存为“true”或“false”。 如果给定的 comName 在日志中并且也在 MySQL 表中,则表示它已“连接”。如果给定的 comName 在 MySQL 表中但不在日志中,则表示它已“断开连接”。

此日志文件每 2 分钟更新一次,这意味着我必须每两分钟进行一次所有这些检查,因为:

  • 此文件可以有需要插入到表中的新 comName。
  • 如果 comName 在表中但不在日志中,我需要在 MySQL 表中评分为断开连接。

该函数将由 crontab 每分钟执行一次。

function ovpnParser($con, $pathlog){
$inclients = false;
$handle = fopen($pathlog, "r");
$inclients = false;
$sql2 = "SELECT comName FROM vpn";
$query2 = mysqli_query($con, $sql2);


while(!feof($handle)){
$line = fgets($handle, 4096);

if (substr($line, 0, 11) == "CLIENT_LIST")
 {
   if (preg_match("/CLIENT_LIST\t{1,}UNDEF(.*)UNDEF/", $line))
   {
     $inclients = false;
   }
   else
   {
    $inclients = true;
   }
 }
 if ($inclients)
 {
  preg_match("/CLIENT_LIST(.*)UNDEF/", $line, $conteudo);

  $partes = preg_split("/\t{1,}/", trim($conteudo[1]));

  $sql            = "SELECT comName FROM vpn
                     WHERE  comName = '{$partes[0]}'";
  $query          =  mysqli_query($con, $sql);
  $numeroDeLinhas =  mysqli_num_rows($query);

  if ($numeroDeLinhas == 0)
    {
    $sql = "INSERT INTO vpn (comName, realAddr, virtAddr, byR, byS, since, sinstamp, blockstatus)
            VALUES ('{$partes[0]}', '{$partes[1]}', '{$partes[2]}', '{$partes[3]}', '{$partes[4]}', '{$partes[5]}', '{$partes[6]}', 'true')";
    $query = mysqli_query($con, $sql);
    }
 }
 $inclients = false;
}
}

最佳答案

我只是稍微调整了你的功能。我添加了 update 语句,以防 logentry 已经在数据库中。我还更改了您的查询以使用准备好的语句,因为它们强制执行格式良好的语句。

由于我不习惯 mysqli,可能会有小错误,但这应该向您展示如何处理您的问题。

function ovpnParser(mysqli $con, $pathlog) {
    $handle = fopen($pathlog, "r");
    $inclients = false;

    $stmtCheckIfExist = mysqli_prepare($con, 'SELECT comName FROM vpn WHERE comName = ?');
    mysqli_stmt_bind_param($stmtCheckIfExist, "S", $comName);

    $stmtInsert = mysqli_prepare($con, 'INSERT INTO vpn (comName, realAddr, virtAddr, byR, byS, since, sinstamp, blockstatus) 
                                    VALUES (?, ?, ?, ?, ?, ?, ?, "true")');
    mysqli_stmt_bind_param($stmtInsert, "SSSSSSS", $comName, $realAddr, $virtAddr, $byR, $byS, $since, $sinstamp);

    $stmtUpdate = mysqli_prepare($con, 'UPDATE vpn SET blockstatus = "false" WHERE comName = ?');
    mysqli_stmt_bind_param($stmtUpdate, "S", $comName);

    while (!feof($handle)) {
        $line = fgets($handle, 4096);
        if (substr($line, 0, 11) == "CLIENT_LIST") {
            if (preg_match("/CLIENT_LIST\t{1,}UNDEF(.*)UNDEF/", $line)) {
                $inclients = false;
            } else {
                $inclients = true;
            }
        }
        if ($inclients) {
            preg_match("/CLIENT_LIST(.*)UNDEF/", $line, $conteudo);
            $partes = preg_split("/\t{1,}/", trim($conteudo[1]));
            $comName = $partes[0];
            $realAddr = $partes[1];
            $virtAddr = $partes[2];
            $byR = $partes[3];
            $byS = $partes[4];
            $since = $partes[5];
            $sinstamp = $partes[6];

            mysqli_stmt_execute($stmtCheckIfExist);
            $result = mysqli_stmt_get_result($stmtCheckIfExist);
            $numeroDeLinhas = mysqli_num_rows($result);

            if ($numeroDeLinhas === 0) {
                mysqli_stmt_execute($stmtInsert);
            } else {
                mysqli_stmt_execute($stmtUpdate);
            }
        }
        $inclients = false;
    }
}

关于php - 比较来自 MySQL 表和日志文件的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38189980/

相关文章:

php - 什么是重负载 LAMP 应用的最佳硬件配置

php - 安装了 Memcached(理论上),PHP 无法使用 memcache_connect()

mysql - 为什么我在 Rails 中得不到此查询的结果?

sql - MySQL SELECT 语句可以在不指定列名的情况下工作吗?

移动站点后 PHP 404

php - 如何使用 PHP 包含上述根目录

PHP PDO 按列名分组查询结果

php - Mysql 存储过程未按预期运行

mysql - 如何在存储过程中使用类似语法

mysql - 查询结果间歇性返回为只读 "could not determine a unique row identifier (MySQL server has gone away)"