我有一个PHP 5.3.4项目,我需要解析日志文件并向用户显示摘要。日志文件格式(在我无法控制的范围内)看起来大致如下:
BEGIN GROUP: my group
<TESTCASE ID=1>
*** Test Name: Some Test
</TESTCASE RESULT="PASSED">
END GROUP: my group
BEGIN GROUP: another group
<TESTCASE ID=1>
*** Test Name: Some other Test
</TESTCASE RESULT="PASSED">
BEGIN GROUP: sub group
<TESTCASE ID=2>
*** Test Name: Foo
</TESTCASE RESULT="FAILED">
END GROUP: sub group
<TESTCASE ID=3>
*** Test Name: Bar
</TESTCASE RESULT="PASSED">
END GROUP: another group
我想我首先要将日志文件解析为一组这样的对象:
abstract class ResultBase
{
// name of this result element
private $name_ = null;
// line number in the result log corresponding ot this element
private $line_ = null;
// ...
}
// defines a Group element from the logfile
class Group extends ResultBase
{
// array of ResultBase-derived child elements belonging to this group.
private $children_ = null;
// ...
}
// defines a TestCase element from the logfile
class TestCase extends ResultBase
{
// test case id
private $id_ = null;
// "passed" or "failed" result
private $result_ = null;
// ...
}
class LogFile
{
// array of ResultBase-derived elements that constitute the log
private $elements_ = null;
}
然后打印对象:
function Print( $log_file )
{
// some recursive print algorithm...
}
我是PHP的新手,所以如果以上是错误的方向,请告诉我。
我正在寻找一些应用模式以及一些关于如何实现它的伪代码建议。
function Parse( $log_file_name )
{
$logfile = new LogFile();
// what goes here???
return $logfile;
}
Print(Parse('C:\mylogfile.log'));
答案 0 :(得分:0)
你可以这样做:
$log = new LogFile('C:\mylogfile.log');
$log->parse();
printf("Log has %d groups.\n", $log->getGroups()); # Log has 3 groups.
LogFile
只是从SplFileObject
延伸:
class LogFile extends SplFileObject {
private $groups;
public function rewind() {
$this->groups = 0;
parent::rewind();
}
public function current() {
$line = parent::current();
if (substr($line, 0, 13) === 'BEGIN GROUP: ') $this->groups++;
return $line;
}
public function parse() {
foreach($this as $line);
}
public function getGroups() {
return $this->groups;
}
}
也许这会给你一些指示。一个更好的变体是装饰器,它接受任何迭代器,这样可以使事情变得更加灵活:
$log = new SplFileObject($logFileName);
$parser = new LogFileParser($log);
$parser->parse();
printf("Log has %d groups.\n", $parser->getGroups());
class LogFileParser extends IteratorIterator
{
private $groups;
public function rewind() {
$this->groups = 0;
parent::rewind();
}
public function current() {
$line = parent::current();
if (substr($line, 0, 13) === 'BEGIN GROUP: ') $this->groups++;
return $line;
}
public function parse() {
foreach($this as $line);
}
public function getGroups() {
return $this->groups;
}
}