Join David Powers for an in-depth discussion in this video Inspecting single directories with DirectoryIterator, part of Up and Running with the Standard PHP Library.
- To traverse the contents of a directory, you have a choice of DirectoryIterator and FilesystemIterator. In this video we will focus on DirectoryIterator. In my SPL testing site I've created a page called directory.php, and we'll use that to create a DirectoryIterator to inspect the common directory. So create a variable file iterator and new DirectoryIterator, and we pass that as an argument the path to the directory we want to traverse, so that's common.
We can now iterate over that with a foreach loop. So it's our iterator dir, we'll give it an alias for each item inside the loop of file, and then inside the loop we'll use echo to see what file shows us, and then we'll have a line break. So if we save that and then load it into a browser, we get a list of the three sub-directories, data, documents, and images. We also get the two dot files that represent the current and parent directories.
But we haven't burrowed down into the sub-directories. DirectoryIterator is capable of traversing only a single directory. So let's change the directory we're examining so we can see some actual files. Go back to the editing program, and we'll look at the images folder, which is inside common. Then we'll save that. We're going to be reloading the browser quite a lot, so what I'm going to do is change the size of my editing program, and just expand that, and then refresh the browser.
We've now got a list of all the files inside the common images folder, but we've still got those two dot files at the top. PHP's got a function called is file that tests whether something is a file. So let's try using that in a conditional statement to filter what's being displayed in the loop. We only want the files. So a new line on line four, if is file, we'll pass it file, and then we'll put that statement there on line five inside that conditional statement.
We'll save that and refresh the browser. Hey presto, we've got an empty page. To find out what's happening, let's inspect file with var dump. So back in the editing program, on line four a new line, var dump, we'll pass it file, save and refresh the browser. Aha, it now becomes clear what we have is an object, a DirectoryIterator object. What's happening inside our foreach loop when we use echo is that PHP is invoking the DirectoryIterator objects to string method to display the name of the current file or directory, but because we're dealing with an object, this is file doesn't work on line five.
What we need to do is to use the object's is file method, sounds the same but it's different. We don't need var dump anymore, so let's just get rid of that, then we'll get rid of the is file function, and then we use the arrow operator on file, and is file all is one word, followed by some parentheses. If we save that and then reload in the browser, the dot files have gone and only the files are left. The DirectoryIterator object has many more methods than is file, and we'll look at them in detail when we examine SPL file info later in this chapter.
But let's just use one to display the current object's relative path. So on line six, again we're using the arrow operator, we'll have getPathname, and if we save that and refresh the browser, we now get the relative path followed by the file name. I'm testing on Windows, we get this rather strange mixture of forward and backslashes, but that doesn't really matter, and we'll find out how to deal with that a little bit later in this chapter.
Iterators have both keys and values, so let's change the foreach loop to examine the key of each object as well. So on line three we'll add in key and the double arrow operator file, and then on line six we'll echo the value of key, and we'll have a colon there, and if we save that and refresh the browser we can see that the key is in fact a number. The reason that the numbers begin a two is because we're using is file.
We're eliminating the dot files there at index zero and index one. Normally you do whatever it is you want to do with the file inside the foreach loop, but let's say you want to create an array of files. Let's see what might happen. We'll just comment out line six, and then on line seven we'll add a new line, and there we'll create an array called files. We'll use bracket notation just to add to that array as we go through the loop.
We'll add file. We'll add our object. So we should have an array of objects, of DirectoryIterator objects. After the loop, if we then use echo, and we'll look for files1, so that will be the second element, and then getfilename. If we save that we hope that we'll get the file name of the second element in our files array. But no, we've got a blank screen again.
This is a rather strange quirk of the way in which DirectoryIterator works. If you want to save them to an array, you need to clone them as you pass them to the array. So that's the clone keyword, and then if we save that again, this time we should get the file name correctly, and there it is indeed, the second file name in our files array. We've used our DirectoryIterator to inspect only the name and relative path of each file, but as you'll discover later in this chapter, you can use iterators to perform a wide range of operations on files.
DirectoryIterator traverses a single directory, providing access to everything at the top level of the directory, including the dot files. It's important to remember that the current element inside the loop is neither the file nor the file name, it's a DirectoryIterator object that contains a reference to the file. To store these objects in an array, you need to clone each one before adding it to the array. In the next video we'll compare DirectoryIterator with its close relation, FilesystemIterator.
- Using SPL iterators
- Inspecting directories
- Working with text files
- Exporting and extracting data
- Filtering data
- Converting between arrays and iterators
- Combining and merging iterators
- Creating a repeat sequence with InfiniteIterator
- Working with data structures