我的场景如下:我有一个函数可以解析一个日志文件(超过 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/