当主题正在阅读文本文件时,我没有运气。我有一个小脚本来读取日志文件(实时更新)但我想将一些数据发送到DB。
问题是,如果我没有从文件末尾读取统计信息,我将在数据库中获得重复的条目。这不可能发生!
// Keep alive
for (;;)
{
$handle = fopen("data.log", "r");
if (!$handle) die("Open error - data.log");
while (!feof($handle))
{
$line = fgets($handle, 4096);
// If match with, I output the result
if (strpos($line, ':gshop_trade:') > 0)
{
if (!preg_match('/([\d-: ]+)\s*.*\sformatlog:gshop_trade:userid=(\d+):(.*)item_id=(\d+):expire=(\d+):item_count=(\d+):cash_need=(\d+):cash_left=(\d+).*$/', $line, $data))
{
echo "Parsing error on line: {$line}";
}
// show the data
}
}
sleep(5);
}
这个脚本正在运行,但正如我上面提到的,我需要将数据发送给BD。但是,我还需要让脚本运行,使用当前代码,脚本匹配所需的字符串,而不是等待data.log
上的新条目,他再次开始读取整个文件。
我看到这个question here并且我测试了但是没有用。当我启动生成" data.log"的服务时,我将启动脚本。但为了防止数据库中的重复条目,我需要阅读最后几行。
我该怎么做?
答案 0 :(得分:1)
也许你可以使用file_get_contents,爆炸并向后读取数组?
$arr = explode(PHP_EOL, file_get_contents("data.log")); // or file("data.log");
$arr = array_reverse($arr);
foreach($arr as $line){
// do stuff here in reverse order
}
从上面的评论中我建议这种方法只使用代码中的新数据 它将读取您的日志和文本文件,其中包含上次读取的内容 删除上次读取的内容并使用代码中的新数据。
$logfile = file_get_contents("data.log");
$ReadData = file_get_contents("readdata.txt");
$newdata = str_replace($ReadData, "", $logfile); // this is what is new since last run.
file_put_contents("readdata.txt", $logfile); // save what has been read.
$arr = explode(PHP_EOL, $newdata);
foreach($arr as $line){
// do your stuff here with the new data.
}
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="refresh" content="5"> <!-- This will run the page every five seconds.
</head>
</html>
答案 1 :(得分:1)
使用ftell()跟踪上一次读数的文件偏移并将结果保存在变量中,并在使用{{3重新打开它以进行下一次读取时跳转到文件中的偏移量}}
$lastPos = 0;
for (;;)
{
$handle = fopen("data.log", "r");
if (!$handle) die("Open error - data.log");
fseek($handle, $lastPos); // <--- jump to last read position
while (!feof($handle))
{
$line = fgets($handle, 4096);
$lastPos = ftell($handle); // <--- maintain last read position
// If match with, I output the result
if (strpos($line, ':gshop_trade:') > 0)
{
if (!preg_match('/([\d-: ]+)\s*.*\sformatlog:gshop_trade:userid=(\d+):(.*)item_id=(\d+):expire=(\d+):item_count=(\d+):cash_need=(\d+):cash_left=(\d+).*$/', $line, $data))
{
echo "Parsing error on line: {$line}";
}
// show the data
}
}
sleep(5);
}