Implementation of logging and subsequent reading from the log

Good time. You need to implement a log like this:

<>07.11<\>
   <>01<\>
      [id][description][date_entered];
      ...
   <>02<\>
      [id][description][date_entered];
      ...
   <>dd<\>
<>08.11<\>
   ...
<>mm.yy<\>
   ...

And then read the information by month and day. How to implement it competently and with what help? Those. for example, write to a text file and then create a function that will look for the desired position and return “[id][description][date_entered]; …” for each day of the month? Or is there a more convenient implementation, XML?


Answer 1, authority 100%

A simple implementation

$message = array(
  'id' => 15,
  'date' => '01.07.2011',
  'message' => 'raz raz raz'
  )
function placeMessage($logfile, $msg) {
  if (!$f = @fopen($logfile, 'a+')) return false;
  fwrite($f, $msg['date'].'#'.str_replace("\n", '##N##', serialize($msg)));
  fclose($f);
  return true;
  }
function getMessage($logfile, $date) {
  $result = array();
  if (!$f = @fopen($logfile, 'r+')) return $result;
  while ($str = @fgets($f)) {
    list($dateMsg, $msg) = explode('#', $str, 2);
    if ($date == $dateMsg) $result[] = unserialize(str_replace('##N##', "\n", $msg));
    }
  fclose($f);
  return $result;
  }

In general, yes, in your case, the database is more suitable (if possible).


Answer 2, authority 100%

Simple text files are better suited for logging. To format the logs, you can use the built-in implementation fputcsv()

$log = array(
    time(),
    '127.0.0.1',
    'Some message'
);
$fp = fopen('application.log', 'a');
fputcsv($fp, $args);
fclose();

And accordingly search:

$from = strtotime('2011-15-06');
$to = strtotime('2011-15-07');
$fp = fopen('application.log', 'r');
while ( ($log = fgetcsv($fp)) ) {
    if ($log[0] < $from) {
        continue;
    }
    if ($log[0] > $to) {
        break;
    }
    $log[0] = date('r', $log[0]);
    vprintf('[%s] %s: %s', $log);
}
fclose();

Answer 3, authority 100%

If stored in a file, it is better to get rid of unnecessary information inherent in the CML format (stored in CVS) so as not to waste time parsing data:

--year;month;day;id;description;date_entered;
2011;03;12;01;Hello Word;''

If you still want to store it in XML, then you should bring it to a more acceptable form:

<year value="2011">
  <month value="01">
    <day value="15">
      <!--   -->
      <item>
        <id>a</id>
        <desc>b</desc>
        <date>c</date>
      </item>
      <item>
        <id>a2</id>
        <desc>b2</desc>
        <date>c2</date>
      </item>    
      <!--   -->
      <item id="a" desc="b" date="c" />
      <item id="a2" desc="b2" date="c2" />
    </day>    
    <day value="16">
      ...
    </day>    
  </month>
  <month value="02">
    ...
  </month>
</year>

It’s a no brainer that tag names should be shortened to reduce the overall amount of data and the time spent parsing and reading them. Therefore, this option would be more optimal:

 <item year="x" month="y" day="z">
    <id>a</id>
    <desc>b</desc>
    <date>c</date>
  </item>

or

<items year="x" month="y" day="z">
  <item id="a" desc="b" date="c" />
</items>

You can easily process the HML using XPath, but if this option is not suitable for you, you can search for means that allow you to work with HML as with the database (unfortunately, I do not remember the names).