PHP to display recent files.

brigham

New Member
Messages
11
Reaction score
0
Points
0
I would like for the homepage of a site to display only the three most recent news items or updates in chronological order. I'm currently using php to reference a directory that contains all news updates as individual flat text files. Each file is named for the date it was created (20090722 would be a news item created on 22 July, 2009).

The script looks into the directory and selects the first three files encountered to be included on the home page. The files are named by their creation date which will result in a logical order.

Here's the script that calls and displays the three most recent updates.
PHP:
<?php
if ($handle = opendir('updates/')) { 
      $i = 0;
      while(($file = readdir($handle)) && $i < 3) {   // Limits the script to display only
           if ($file != "." && $file != "..") {     // 3 items if they aren't directory references
                include ("updates/$file");                               
                $i++;
              }
        }
    closedir($handle);
    }
?>

Is there a better way to accomplish this? Are there security problems with this? Thanks for any help.
 
Last edited:

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
The files returned by readdir are in filesystem order, which might be sorted by name (in ascending order--you want descending) but can just as easily be by creation date or an arbitrary order. X10 runs off of Linux and currently uses ext3; I believe entries in ext3 directories are unsorted. scandir will return the contents of a directory as an array of filenames sorted in ascending or descending order.

PHP:
$news = array_slice(scandir('updates', 1), 0, 3);

If you have a large number of news items, the above will get unwieldy as scandir (or any implementation that scans the directory) will need to sort the list of files each time the page is opened. You could cache the three most recent files in another file (either in a different directory, or in 'updates' but lexically lower than the news items, e.g. '.recent.txt' or '!recent.txt'), updating it when its modification time is older than the directory's modification time.

Alternatively, store the news items in a database.
Code:
CREATE TABLE news (
  id INTEGER PRIMARY KEY AUTO_INCREMENT,
  date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  title VARCHAR(64) NOT NULL,
  subtitle VARCHAR(128) DEFAULT NULL,
  body VARCHAR(65024) NOT NULL, -- could also make body TEXT
  INDEX (date)
);
Statement to store values:
Code:
INSERT INTO news (title, body) VALUES ('Sticks Nix Hick Pix', 'Current visit to Hollywood...'), ... ;
Note that you don't need to specify the date when inserting; news items are automatically dated upon insert. Statement to retrieve the 3 most recent news items:
Code:
SELECT date,title,subtitle,body  FROM news ORDER BY date DESC LIMIT 3;
Just make sure you use PDO and prepared statements if you go this route.

Another option would be to put all the news items into a single file, adding new items to the top and separating items with some unique string that won't appear in the items. To make sure of this, you can prefix a space to any line in a news item that happens to be the separator and strip spaces from lines (after testing for the separator).

Performance-wise, the single file is probably the fastest, as long as you don't need any other operations on news items. If you need the n-th most recent news item, for instance, the database will probably be fastest.

As for security, you mostly need to worry about user input. It's rather hard to exploit code that behaves the same no matter what input it's sent. Outside security holes in scripts, there's one other potential hole: the files containing the news items in your implementation will be directly readable by visitors. If that's a problem, just move 'updates' outside the DOCUMENT_ROOT hierarchy.
 
Last edited:

xav0989

Community Public Relation
Community Support
Messages
4,467
Reaction score
95
Points
0
As always, mission provides a great and very well explained answer ! :biggrin:

Keep in mind, and I speak out of personal experience, that using flatfile systems may sound like the easiest, but the problem is that there could be performance reductions (what if all the users of a servers want to access a file at the same time). When I moved to only using database, I found that my site was responding faster, and the data was safer as well.
 

descalzo

Grim Squeaker
Community Support
Messages
9,373
Reaction score
326
Points
83
PHP:
if ($handle = opendir('updates/')) { 
      $i = 0;
      $allfiles = array();
      while(($file = readdir($handle)) ) {  
           if ($file != "." && $file != "..") {   
                $allfiles[] =  $file ;    
            }
      }
      closedir($handle);

      rsort( $allfiles );  # sort names in reverse order  
      while( $i < 3 ){
         $to_include = 'updates/' . $allfiles[$i] ;
          include ("$to_include"); 
         $i++ ;
      }
}
 
Last edited:

brigham

New Member
Messages
11
Reaction score
0
Points
0
Question resolved. Thanks!

Thanks so much for the help. I was trying to avoid using tables (no real reason), but I guess I'll quit being silly about it.

Thanks again to all three responders.
 
Top