When talking about any kind of server-side language, like PHP or ASP, you will often find the term “database” not too far behind. It is the preferred choice for storing data on the web after all. Another option is to use a text file. The problem with text files is that they are not typically secure, can be easily read, and don’t offer any of the features like referential integrity (relationships). However, one thing that files do have is the ability to quickly modify data that doesn’t need to be secure, can be easily viewed or perhaps isn’t related to any other data. Who really cares if someone sees a text file listing a bunch of article topics or shouts from a publicly viewed shoutbox? As long as they can’t modify the content directly, no problem. For this reason they are great for logs, list data, even sources of information for other services to use. So flat files have their place and I will show you how we can use one to store a queue of article topics between script executions in PHP right here on the Programming Underground!
What is a queue? Well it is essentially a data structure where you have a list of data (a collection) that is kept in order and the data added to it is added to the top of the list and data removed comes from the bottom of the list. You may know this as a FIFO or First In First Out data structure. To help you think of how this works imagine a line of people standing outside of a video game retailer. They are all wanting to be the first to get a new game that is launching that day. Those who add themselves first to the line are the ones that will get the video game first and are the ones that leave first to go play it. “First come first served.” I suggest you look up the term FIFO on the web for any further information on these types of systems. These types of structures are encountered all the time in programming and so it is helpful to know how they work and try implementing a few of them in your creations. Unless of course your creation leads to the end of humanity, then in that case don’t try them!
In our example below we use a simple text file on our web server to keep a list of titles for some articles. I used this system in one of my projects recently to keep track of titles I have already shown to the public. When I select a new title, I want to check this list to make sure that the title hasn’t already been shown (in the last 75 topics) and to pick another title in case of a repeat. Whenever I determine that a title has not been shown yet, I can add it to the front of the text file list. If at any time that list grows beyond 75 items, I also want to trim the list down by removing a title from the end of the list (the oldest title).
The result is that I have a text file keeping track of the last 75 article titles I have shown the public and no more. In addition, since the list essentially trims itself with a limit, I don’t have to worry about going and cleaning out the text file at some later date. It keeps itself in check. You could use such a system to easily log bits of information that you may want to view later, keep for later access by a script (persistence), or serve as a data source for other applications. All this without the file taking up massive resources in your database and without a lot of query execution.
Let’s check it out below….
<?php // Title Manager class (essentially a queue) that uses a simple text file for storage class TitleManager { private $filename = "titlemanager.txt"; private $queueLimit = 75; private $titles; // Upon creation, load up our titles from the file public function __construct() { $this->titles = array(); $this->loadTitles(); } private function loadTitles() { if (file_exists($this->filename)) { $this->titles = file($this->filename, FILE_SKIP_EMPTY_LINES); } } // Add a title to the queue and if we are at our limit, drop one off the end. public function enqueue($strTitle) { if (!empty($strTitle)) { array_unshift($this->titles, $strTitle . "\n"); if (count($this->titles) > $this->queueLimit) { $this->dequeue(); } } } // Remove a title item from the end of our list public function dequeue() { if (count($this->titles) > 0) { return trim(array_pop($this->titles)); } return ""; } // Save the contents of our array back to the file. public function save() { if (file_put_contents($this->filename, $this->titles)) { return true; } return false; } // Check if an item is already in our list. // Note: We could have also used in_array here instead of a loop. public function isTitlePresent($strTitle = "") { if (!empty($strTitle)) { foreach ($this->titles as $title) { $trimmedTitle = trim($title); $strTitle = trim($strTitle); if (strtolower($strTitle) == strtolower($trimmedTitle)) { return true; } } return false; } return -1; } // Mainly a debug function to print our values to screen. public function printValues() { foreach ($this->titles as $value) { echo "$value<br/>"; } } } ?>
I have wrapped all this functionality up into a small class called “TitleManager” which has a few main methods. Upon creation of this class it references a file in the local directory which I called “titlemanager.txt”. You could have made this a dynamic setting that you pass in through the constructor, but I knew I wasn’t really going to use this for anything else in the foreseeable future. So to be lazy I made it a hardcoded name. If I wanted to change it later, it wouldn’t be hard to do anyways. In addition to this constructor, I created a few methods called enqueue() for adding items to the top of the list, dequeue() for removing items from the end of the list, save() for basically dumping the array contents back out to the file, isTitlePresent() a boolean function to check if a title is already found in our list and printValues() a debug function to show the contents currently being managed by the class.
The methods are not complicated and using PHP’s great file handling functions, like file() and file_put_contents(), I can easily bring the file in and out of a PHP array. Creating the class will load up the file (if it exists) and put the titles into an array for us. We can add and remove using the enqueue() and dequeue() methods as we see fit, then save() them back to the file.
One place you could use this class is for website event logging. You could keep track of the last X number of events that happen on a website. The only place this would really need some modification, if you were to use it for logging, is the isTitlePresent() function. This would probably become a useless function given that you would not really want to check if an event had already occurred. Each event would be unique to itself and already have a unique timestamp associated with it. But other than that, it should prove very useful to you.
Implementing something like this through a database would involve executing select queries, reading into an array, making updates and deletes as appropriate and could all become very messy for a simple FIFO system. So if you need something basic and simple for handling logging or keeping track of a list that you don’t mind people reading at any point, this may be your answer.
Feel free to help yourself to the code and modify it as you see fit. As with all code on the programming underground, it is in the public domain and can be used for academic or commercial purposes. Enjoy and thanks again for reading! 🙂