PHP: Flat File Manager
by Vasilios

If you ever find yourself writing a PHP script that needs to store data, you’re probably going to ask yourself this: should I use flat files or MySQL databases?
If you’ve never worked with flat files or MySQL databases, I would suggest starting out with flat files. They are easier to work with when you first begin learning how to store data. Flat files work well because they are just normal files, so you don’t have to create anything special, everything is right where you need it! They even have their own PHP functions to manipulate them. Some scripts that use flat files are Jem’s Bella~ Series and FlatPress.
Some tutorials and resources you might want to read include: Beginner’s Guide To PHP Part One, Part Two, Part Three, Part Four and Working with CSV Flat Files Storage. CSV flat file storage refers to when you store data in flat files separating each “row” with a comma.
When I began working with flat files, the problem that I came by time after time again was blank lines in the file after editing or deleting “data items”. After about an hour of coding around this problem I have discovered a solution. It all lies in a simple class. Before I even get into the actual code, I would recommend downloading XAMPP so you can test out your script offline before putting it up on your website.
Now we can begin the actual code.
Defining the Class
<?php
class FlatFile {
var $file;
var $items;
var $total;
var $php;
var $the_php;
}
?>
We start the code out with defining the class (FlatFile) and some variables.
$file: The file that we are working with.
$items: The contents of $file.
$total: The total number of items.
$php: Tells the script if the code is a PHP file.
$the_php: The PHP in the file, depends on $php.
Constructing the Constructor
function FlatFile($file = ‘’) {
$this->items = $file;
$this->set_items();
if ($file == ‘’) return;
elseif (!file_exists($file)) die("<code>$file</code> is not a file");
$this->items = array();
$this->total = 0;
$this->php = (preg_match(’/(php|php3|phtml)/’, end(explode(’.’, $this->file)))) ? true : false;
$this->the_php = ‘’;
}
We define the function as FlatFile because it is a constructor. Therefore it has the same name as the class. We’ll allow one argument, the file. The main purpose of this function is to set the default variables. The regex in preg_match() just checks to see if the file has a .php, .php3 or .phtml extension. $this->set_items() calls the set_items function, which is the next step. If you’ve never worked with Object Oriented PHP, you access variables and functions using $this.
set_items() function
function set_items() {
$this->items = array();
$contents = file($this->file);
if ($this->php === true) {
$this->the_php = $contents[’0’];
array_shift($contents);
}
if (is_array($contents) && count($contents) > 0) {
$contents = array_map(’trim’, $contents);
$this->items = $contents;
$this->total = count($this->items);
}
return $this->items;
}
We set the items variable to an array because if this function is called a second time we don’t want the old items to return. We use file() to retrieve the contents of $this->file. The next if statement is used to check if $this->php is set to true. If the if statement returns true, the first item in the array is the value of $this->the_php and then the first item is shifted off with array_shift(). array_map() is applied because we don’t want any trailing blank lines. Then we just set the items and total.
write_items() function
function write_items() {
if ($this->php === true && !empty($this->the_php))
$data = implode("\n", array_map(’trim’, $this->items));
$fh = fopen($this->file, ‘w’) or die("Couldn’t open <code>{$this->file}</code> for writing.");
array_unshift($this->items, $this->the_php);
$result = fputs($fh, $data);
fclose($fh);
return $result;
}
Obviously this function will write the items to the file. We’ll open the file for writing with fopen() in write mode. Then we’ll use the same if statement as we did in the set_items function, with the addition of making sure the php is set. If the statement returns true this time, we use array_unshift(), the opposite of array_shift, to read the PHP part to the items array. Finally, the items array is trimmed and imploded with a new line, and written to the file.
Taking it a Set Further: add_item(), delete_item() and edit_item()
function add_item($item) {
function delete_item($index) {
function edit_item($index, $item) {
$this->items[] = $item;
return $this->write_items();
}
if (empty($this->items[$index]))
die(’The requested item isn\’t set.’);
else {
unset($this->items[$index]);
return $this->write_items();
}
}
if (empty($this->items[$index]))
die(’The requested item isn\’t set.’);
else {
$this->items[$index] = $item;
return $this->write_items();
}
}
These three functions are all optional. add_item just adds an item to the items array, nothing more to it. delete_item() deletes an item from the list with the index ($index) and calls write_items().
Remember, indexes start at 0, not 1! edit_item() does what it says, edits an item! ‘Call’ this function with the index of the item you want to edit and the new content of the item. This function also calls the write_items() function.
Usage
<?php
if ($manager->total > 0) {
include('FlatFile.php');
$manager = new FlatFile('flat-file.txt');
foreach($manager->items as $index => $item) {
$item = explode('|', $item);
echo '<p><strong>'.$item['0'].': </strong>'.$item['1'].'</p>';
}
}
?>
To have the example work, you must have the flat file class in a file called FlatFile.php and flat-file.txt must exist.
Vasilios is the owner of Another-Perfect-World.org.
