Working with files and SPL

The Standard PHP Library (SPL) has been around for a while now. Most of it was introduced in PHP 5.3 back in 2009,  but some of it has been around since PHP 5.0 released way back in 2004. The only experience I had with the SPL prior to writing this post was using a few of the objects based on recommendations from Stackoverflow answers. So I never really delved into the complete library to see what is has to offer. The biggest hurdle I found with learning more about the SPL is that the classes are not that well documented. The best documentation is from the comments in most cases!

I’m sure most of us have had to work with files in some manner. For me it usually takes the form of a logger or parser (CSV or XML). One of the things I have always thought would be helpful is an object to wrap the fopen, fwrite, fread, fclose functions so you didn’t need to maintain the file handle. Enter the SPL. It wraps a lot of the reading, writing, searching, and parsing into easy to use objects so that you don’t need to preserve that file handle in a variable.

SplFileInfo

SplFileInfo offers a way to get information about a file (as the name would suggest). Because it handles some of the more basic aspects of working with files, it won’t come as a shock that a lot of the other file related SPL objects extend SplFileInfo. Need to get the extension? Use SplFileInfo::getExtension(). How about the last modified time? SplFileInfo::getMTime(). Is the file a symbolic link to a different file? SplFileInfoisLink() to check and SplFileInfogetRealPath() to resolve to the actual location. The only thing it doesn’t do is handle reading and writing, but that is where SplFileInfo::openFile() comes into the picture. The openFile method will return an instance of SplFileObject that can be used to do reading/writing.

SplFileObject

SplFileObject inherits from SplFileInfo, so it has all of the same capabilities plus being able to read and write.

CSV Parsing

If you need to parse a CSV you can use the setFlags() method before parsing a file to set flags that will change how it handles parsing. SplFileObject::setFlags(SplFileObject::READ_CSV) sets the stage for parsing a csv file.  While on the topic of csv files… SplFileObject::setCsvControl() allows you to set the delimiter, enclosure, and escape character.

Reading Lines

To read the file line by line it’s as easy as using a loop.

foreach ($obj as $line) {
// SplFileObject::__toString() is set as an alias of SplFileObject::current(), which makes echo'ing the object return the current line.
echo $line;
}

DirectoryIterator

DirectoryIterator is used to list files and subdirectories. Like SplFileObject, it inherits from SplFileInfo. I’ll discuss iterators in another post, but for the sake of understanding the power of DirectoryIterator it is enough to know they are most often used in loops.

foreach (new DirectoryIterator('/path/to/dir') as $file) {
    echo $fileInfo->getFilename() . "\r\n";
}

This will yield something like:

.
..
filename.txt
directory
image.jpg

One useful method available in DirectoryIterator but not available in SplFileInfo is DirectoryIterator::isDot(). This returns true if the “file” is a “.” or “..” system file.

RecursiveDirectoryIterator

RecursiveDirectoryIterator is the recursive version of DirectoryIterator. It will go down into the subdirectories and list files and subdirectories and so on and so on.

$files = new RecursiveDirectoryIterator('/path/to/dir');
$files = new RecursiveIteratorIterator($files);
foreach ($files as $file) {
    echo $file . "\n\r";
}

This will yield something like:

.
..
filename.txt
directory
directory/file.txt
directory/subdirectory
directory/subdirectory/image.jpg
image.jpg

Closing

I only touched on some of the basic and useful parts of the SPL that I found to make working with files much easier and more logical. There is so much more for you and I to learn about them though.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>