2014-07-07 38 views
1

我想实现一个平面文件博客系统。我想博客加载了一堆文本文件,它的文章,文本文件格式看起来像这样使用PHP读取部分文本文件

{ 
    "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. 

由两个部分组成的文章的文本文件,第一部分是元,而第二是为了内容。

当博客被加载,我只第一部分,所以后来我可以操纵的一些菜单和列表浏览数组。

这是我现在使用的编码。

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

我有这个编码时执行没有问题,但我正在寻找一个便宜的过程只加载第一部分代替负荷然后将整个文件后爆发,在我的编码,因为博客可能会处理数百篇文章。我不介意如果我必须将一些特殊标记放入文件中以分离它的元和内容。

请帮忙。

+1

当然数据库(甚至SQLite的)会比一个文本文件,基于解决方案更理智的做法? –

回答

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

假设你的元数据不会在一个块跨越8192个字节,你可以这样做:

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