我有几个文件要解析(使用 PHP),以便将它们各自的内容插入不同的数据库表中。
第一点:客户给了我 6 个文件,5 个是 CSV,其值用逗号分隔;最后一个不是来自同一个数据库,它的内容是基于表格的。
我构建了一个 FileParser,它使用 SplFileObject 在文件内容的每一行上执行一个方法(基本上,使用每个数据集创建一个实体并将其保存到数据库中,使用 Symfony2 和 Doctrine2)。
但是我无法使用 SplFileObject 解析基于制表的文本文件,它不会像我期望的那样将内容拆分成行...
// In my controller context
$parser = new MyAmazingFileParser();
$parser->parse($filename, $delimitor, function ($data) use ($em) {
$e = new Entity();
$e->setSomething($data[0);
// [...]
$em->persist($e);
});
// In my parser
public function parse($filename, $delimitor = ',', $run = null) {
if (is_callable($run)) {
$handle = new SplFileObject($filename);
$infos = new SplFileInfo($filename);
if ($infos->getExtension() === 'csv') {
// Everything is going well here
$handle->setCsvControl(',');
$handle->setFlags(SplFileObject::DROP_NEW_LINE + SplFileObject::READ_AHEAD + SplFileObject::SKIP_EMPTY + SplFileObject::READ_CSV);
foreach (new LimitIterator($handle, 1) as $data) {
$result = $run($data);
}
} else {
// Why does the Iterator-way does not work ?
$handle->setCsvControl("\t");
// I have tried with all the possible flags combinations, without success...
foreach (new LimitIterator($handle, 1) as $data) {
// It always only gets the first line...
$result = $run($data);
}
// And the old-memory-killing-dirty-way works ?
$fd = fopen($filename, 'r');
$contents = fread($fd, filesize($filename));
foreach (explode("\t", $contents) as $line) {
// Get all the line as I want... But it's dirty and memory-expensive !
$result = $run($line);
}
}
}
}
这可能与我的客户文件的可怕格式有关,但在与他们长时间讨论之后,由于某些可接受的原因(他们方面的限制),他们真的无法为我获得另一种格式,不幸的是。
该文件目前有 49459 行,所以我真的认为内存在这一步很重要;所以我必须让 SplFileObject 工作,但不知道如何。
可以在此处找到该文件的摘录: Data-extract-hosted