In our second article on the standard PHP library, David Fells explains the new Arrray object, introduces Iterators and the ArrayIterator, and discusses some practical examples of their usage. This article assumes a knowledge of how Exceptions work in PHP 5.
In our example above we used an example that traversed a directory and displayed its contents. This is fine if you are simply checking the contents of a single directory, but what if you need to traverse an entire directory tree? Perhaps you may be searching for a file or simply preparing formatted output. The example below demonstrates a simple way of displaying a directory tree for a given path.
First let us discuss the WalkDirectory function. This function takes a DirectoryIterator object as its first parameter and is required. The second parameter, depth, should not be specified by the calling application, as it is used solely to track the depth of the current traversal in the directory tree. The first line of the function grabs an appropriate amount of padding for the current depth level (we use $depth to determine how far to indent a file or directory in our output) and the current directory path name with the getPathName() method.
The next block of code beginning with the while loop is where we begin to traverse the DirectoryIterator. First we put the node from our DirectoryIterator object into a variable $node. We then test if the variable is a non-dot directory (that is, not "." or ".."). If the current node is a directory, we append the return value of another call to WalkDirectory to our current return value. This is where the recursion we mentioned before steps in. Recursion is a topic unto itself but in short, recursion is a function calling itself with a known set of operating conditions until a desired target condition is reached. For a higher quality introduction to recursion than could be provided in this article, read Solving Problems with Recursion by Mohamed Saad (http://www.devshed.com/c/a/Practices/Solving-Problems-with-Recursion/).
If the node is not a directory then it is a file, and we simply append the appropriate amount of padding and the name of the file. The following line advances the iterator one step. Finally, on the last line, we return our return value. If we output the return value, we will see a primitive tree view of the directory we traversed.
The makers of PHP considered this scenario, though, and provided a better way of of recursively iterating structures that require recursion for complete traversal - such as directories, multidimensional arrays and any object with nested objects that use the same type of Iterator.
In short, the introduction of the various interfaces related to Iterators allows PHP developers to strongly implement a sort of regimented object traversal that truly prevents outside code from seeing inside classes' private data. The new features in PHP 5 and the introduction of the SPL are great steps toward improving developers' abilities to develop reusable, loosely coupled classes. Keeping private data private is an important part of this and the ArrayObject, Iterator interfaces and classes come built in to assist the task of creating strong code.
As was mentioned on the previous page during our discussion of recursive iteration, there is another group of Iterators that specifically provide a method for recursive object traversal. These will be the subject of the third and final installment in this series on SPL.