This is part two of our simple CMS or blog in flatfile format. We’ll see how to structure the flat file, and the code needed to read it in.
This code is not optimized, so it’s easier to understand. As we progress in this series we’ll see how to improve coding style.
First of all we have to define the flat file format.
We will need several fields:
- Title – mandatory
- Url – mandatory
- Content – mandatory
- Meta keywords – optional
- Meta description – optional
- Author – optional
- Post date – optional, as unix timestamp
The most straightforward way to tackle this in a flat file would be to separate each element with a special character never to be used in titles or content, say a pipe symbol ‘|’.
Then, we would place all content on a single row and use PHP’s fgets() function to read one line at a time.
There are two problems with this approach: sometimes is handy to include newlines in the file, to make it easier to read and edit. And using a special character, whatever it is, prevents us from using it in the text.
A nice and tidy solution would be to use some sort of XML format, but we are aiming for a short, efficient script -not an exercise in Quality Coding.
A good compromise can be to use a complex separator both for articles and for items inside articles. Let’s say something like: #00# between items and #99# between articles.
The “database” file would therefore appear this way:
1 2 3 4 5 6 |
#00#/#00#This is the Home Page.#00#Micro Flat File CMS#00#Home#00##00##99# My title#00#my-title.html#00#This is the post. It can spawn multiple lines. And have <b>html code</b> inside. #00#Post, article#00#Sample post#00#Admin#00#1251892286#99# Corporate Home Page#00#corporate.html#00#Our mission is to provide nonsense mission statements no one will ever read. #00#Mission, corporate#00#We We We We We...#00##00# |
Looks like a mess, right? Let’s make a simple entry template:
TITLE#00#URL#00#
[anything here will be the post]
#00#TAGS#00#DESCRIPTION#00#AUTHOR#00#TIMESTAMP#99#
Just copy and paste this block to add an entry, then fill in the fields.
As you can see the home page in the first example is marked with a single slash, as using index.html is usually bad for SEO.
How are we going to parse this flat file database in PHP?
First of all, we’ll have to read the file in memory. Then, explode articles and iterate over them. If an article matches the url the user requested, explode this article contents and fill the “Theme”.
To make everything clean and expandable, we’ll begin defining some config variables. Please note this code is very basic so that it’s easier to understand, and is compatible with PHP4 (BTW, if you are using PHP4 upgrade NOW). Feel free to optmize it if you are an experienced programmer.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
$config_db=dirname(__FILE__)."/db.txt"; // location of the database file, change this to something less obvious $config_site="http://www.crivionweb.com"; // absolute url for your domain here $config_theme=dirname(__FILE__)."/theme.html"; // location of the "theme" file, a single html page $config_date="M jS, Y"; // how to format the date function, localize it as needed $found=false; // defaults to page not found $url=basename ($_SERVER['REQUEST_URI']);// this returns the actual file requested by the user if($url=='') $url='/'; // force home page to be the single slash $fp=@fopen($config_db,"rb"); // the @ prevents errors from showing if(!$fp===false && $url!="404.html") // this check saves time if this is a 404 redirect { $data=fread($fp,filesize($config_db)); if(! $data===false ) {// file was read in, we can parse it $articles=explode("#99#",$data); // put each article in an array foreach($articles as $article) { /* now loop all articles looking for the one that contains the url play it safe including #00# markers before and after the url, so that we can link between pages without problems */ $pos=strpos($article, "#00#".$url."#00#"); if($pos !== false) {// this is the article we were looking for $found=true; // now explode the article and exit the loop to save time $items=explode("#00#",$article); break; } } fclose($fp); } } else // issue a 404 redirect and die { header ("HTTP/1.0 404 Not Found 404.html"); exit; } |
With this code, we’ll have $found set to true and the $items array filled if the page was in the database.
We’ll complete the script in the next post, handling 404 errors and implementing the template system.
Leave a Reply