我有一个代理应用程序,它在文本文件中生成日志文件,从一行到下一行不一致。根据行报告的内容,某些数据将存在或丢失。这是一个例子:
2012-08-05 10:48:59 Login.Failure [ip address] 12312191391921
2012-08-05 10:49:05 Login.Success [ip address] 19919292912912 IQi8CaVGiXoPXGy
2012-08-05 12:50:57 Logout 19919292912912 IQi8CaVGiXoPXGy Expired
有七种可能的值,但正如您所看到的,它们并非始终存在。
我想在数据库中输入这些值,以便创建统计信息。到目前为止,我猜我需要查看位置2(0,1,2)的数组,如果它匹配某个字符串,只需要这些项目,如果匹配另一个字符串,只期望这些项目等。
到目前为止,我的想法已经到了打断数组并根据它找到的值添加新条件的程度。我知道,这不起作用,但就我的想法而言,这是可行的:
$output = explode("\n", $output);
foreach($output as $var) {
$tmp = explode(" ", $var);
$dateentered = $tmp[0];
$timeentered = $tmp[1];
$event = $tmp[3];
if $tmp[3]="Login.Failure" then
$IP = $tmp[4];
$username = $tmp[5];
$connection = mysql_connect("localhost", "user", "pass") or die('unable to connect');
mysql_select_db('dbname') or die('unable to select database');
$sql = "INSERT INTO table SET dateentered='$dateentered', timeentered='$timeentered', event='$event', IP ='$IP ', username='$username'";
$result=mysql_query($sql,$connection) or die('Error in query: $query. ' .mysql_error());
else if $tmp[3]="Login.Success" then
$IP = $tmp[4];
$username = $tmp[5];
$session = $tmp[6];
......等等......
我希望能够取得所有成功并总结它们,然后对失败做同样的事情,等等。
你会怎么做?如果有人甚至只是想知道合理的工作流程,我可以从那里构建。我显然只是一个初学者,不过我确实有几页。
感谢所有回复。
答案 0 :(得分:1)
为什么您的数据库结构不是这样的:
2012-08-05 10:48:59 Login.Failure [ip address] 12312191391921 NULL NULL
2012-08-05 10:49:05 Login.Success [ip address] 19919292912912 IQi8CaVGiXoPXGy NULL
2012-08-05 12:50:57 Logout NULL 19919292912912 IQi8CaVGiXoPXGy Expired
或者像这样:
2012-08-05 10:48:59 Login.Failure [ip address] 12312191391921 "" ""
2012-08-05 10:49:05 Login.Success [ip address] 19919292912912 IQi8CaVGiXoPXGy ""
2012-08-05 12:50:57 Logout "" 19919292912912 IQi8CaVGiXoPXGy Expired
在正确的列中维护正确的数据,或者更确切地说,维护同一列中的关联数据应该优先考虑。
为了解决您的问题,我相信这个解决方案可行:
$output; // data gotten from file
$connection = mysql_connect("localhost", "user", "pass")
or die('unable to connect'); // connect to DB
mysql_select_db('dbname') // select DB
or die('unable to select database');
$output = explode("\n", $output); // tokenize input by lines
for($i=0; $i<count($output); $i++) {// for each line
$tmp = explode(" ", $output[i]); // tokenize lines by spaces
$dateentered = $tmp[0]; // set required data
$timeentered = $tmp[1]; // set required data
$event = $tmp[3]; //i think this should be [2]
$IP = ""; // set default value of possible data
$username = ""; // set default value of possible data
$session = ""; // set default value of possible data
$expired = ""; // set default value of possible data
if ($event=="Login.Failure") {
$IP = $tmp[4]; //i think this should be [3]
$username = $tmp[5]; //i think this should be [4]
}
else if ($event=="Login.Success") {
$IP = $tmp[4]; //i think this should be [3]
$username = $tmp[5]; //i think this should be [4]
$session = $tmp[6]; //i think this should be [5]
}
else if ($event=="Logout") {
$username = $tmp[5]; //i think this should be [4]
$session = $tmp[6]; //i think this should be [5]
$expired = $tmp[7]; //i think this should be [6]
}
/*
* Update DB:
*/
$sql = "INSERT INTO table SET "
."dateentered='$dateentered', "
."timeentered='$timeentered', "
."event='$event', "
."IP ='$IP', "
."username='$username', "
."session='$session', "
."expired='$expired'";
$result=mysql_query($sql,$connection)
or die('Error in query: $query. ' .mysql_error()
.'\n\nWhile Processing line $i');
} // closing brace of for loop
mysql_close($connection); // close connection to DB
有关您的代码的问题:
$tmp[2]
;我认为您的索引可能会被1 另外一定要检查我的代码,以确保它的行为与盲目插入数据库一样。我认为我正确地解释了你的问题并提出了一个有效的解决方案,但只有你可以确定。
答案 1 :(得分:0)
您确实需要验证插入数据库的每一行。我可能会使用一个简单的函数来做它,返回一个正确的分隔字符串或一个可以附加到insert语句的数组。
从示例文本的外观来看,文本是制表符分隔的,因此这是一个开始。在功能中你可以爆炸,至少获得单个项目。跟着它,它们似乎一个接一个地变得相当不同,这也很好,这意味着你理解哪些缺失的逻辑应该是容易的。
这个非常简单的代码可以让你入门......
function findMyFields($inputString)
{
$tArray=explode('\t', $string);
if(str_len($tArray[0])==19)
// the dateTime looks to be 19 characters and will stay fixed length
{
$returnString=$tArray[0].',';
}
else
{
$returnString=null.',';
}
// and so on for each field.
return $returnString;
}
答案 2 :(得分:0)
您可以创建一个关联数组,其中键是日志条目类型(Login.Success
,Login.Failure
等),值是一个条目数组。
然后通过第一个键遍历数组。因为您知道每种日志类型需要哪些字段;它只是创建一个模板SQL查询的简单例子(当然有正确的转义)。