使用PHP读取部分文本文件

时间:2014-07-07 05:14:34

标签: php regex file-io

我想实现一个平面文件博客系统。我希望博客加载一堆文本文件作为它的文章,文本文件格式如下所示

{
    "title": "Hangout with friends",
    "slug": "handout-with-friends",
    "date": "06-05-2012",
    "category": "General",
    "tag": "Lifestyle, Social",
    "author": "Someone"
}

### Introduction

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

### Whatever 1

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

### Whatever 2

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

文章文本文件分为2部分,第一部分是元文件,第二部分是内容。

加载博客时,需要第一部分,因此我可以操作某个菜单和文章列表的数组。

这是我现在正在使用的编码。

private function createArticleFromHeader($filelist) {

        $articles = array();

        foreach($filelist as $filename) {
            $header = array();

            $handle = fopen($header_file, 'r');

            $raw = preg_replace("/" . PHP_EOL. "{2,}/", PHP_EOL . PHP_EOL, stream_get_contents($handle));

            $sections = explode( PHP_EOL . PHP_EOL, $raw);

            $meta = json_decode(array_shift($sections), true);

            $articles[] = new Article($meta);
        }

        return $articles;
    }

使用此编码执行时没有任何问题,但我正在寻找廉价流程仅加载第一部分而不是加载整个文件然后在我的编码中将其爆炸,因为博客可能会处理数百篇文章。如果我必须在文件中加入一些特殊的标记来分隔它的元和内容,我不介意。

请帮忙。

2 个答案:

答案 0 :(得分:2)

PHP fgets函数旨在从文件句柄中一次读取一行 由于您不介意在文件中添加内容,因此如果您放置了##########之类的分隔符(或者您的文件中可能找不到的其他内容),则很容易检测到它。

你的例子是:

{
    "title": "Hangout with friends",
    "slug": "handout-with-friends",
    "date": "06-05-2012",
    "category": "General",
    "tag": "Lifestyle, Social",
    "author": "Someone"
}
##########
### Introduction

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse

阅读它的代码看起来像这样:

private function createArticleFromHeader($filelist) {

    $articles = array();

    foreach($filelist as $filename) {
        $header = array();

        $handle = fopen($header_file, 'r');
        $raw = "";
        while (($buffer = fgets($handle)) !== false) {
            if (trim($buffer) == "##########") {
                break;
            }
            $raw .= $buffer;
        }
        $raw = preg_replace("/" . PHP_EOL. "{2,}/", PHP_EOL . PHP_EOL, $raw);

        $meta = json_decode($raw, true);

        $articles[] = new Article($meta);
    }

    return $articles;
}

如果你真的希望一次处理这么多文件,你也应该关闭你的文件句柄,否则你的内存可能会比预期的更快。

答案 1 :(得分:1)

假设您的元数据不跨越一个8192字节的块,您可以使用:

$meta = json_decode(strtok(
    file_get_contents($filename, false, null, 0, 8192), 
    PHP_EOL . PHP_EOL
), true);