PHP - 当行不一致时,如何从文本文件中插入MySQL中的行

时间:2012-08-07 22:33:05

标签: php mysql arrays explode

我有一个代理应用程序,它在文本文件中生成日志文件,从一行到下一行不一致。根据行报告的内容,某些数据将存在或丢失。这是一个例子:

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];

......等等......

我希望能够取得所有成功并总结它们,然后对失败做同样的事情,等等。

你会怎么做?如果有人甚至只是想知道合理的工作流程,我可以从那里构建。我显然只是一个初学者,不过我确实有几页。

感谢所有回复。

3 个答案:

答案 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.SuccessLogin.Failure等),值是一个条目数组。

然后通过第一个键遍历数组。因为您知道每种日志类型需要哪些字段;它只是创建一个模板SQL查询的简单例子(当然有正确的转义)。