Marcus Boerger has done a wonderful job developing the SPL. He also provided many examples using the SPL that can be found in the php5 sources. Just unpack the sources and in the ext/spl/examples directory you have some very nice ones. Thank you Marcus for all your efforts!
Now, a contribution of mine (i think it will be implemented later anyway). The RecursiveIteratorIterator could use a depth limit option. Very useful in many situations (e.g. show just the 1st subdirectory of a list of dirs). I'm sure this can be done in other ways. Here's my 2 cents:
<?php
class LimitRecursiveIteratorIterator extends RecursiveIteratorIterator
{
protected $depth_limit;
public function __construct (Iterator $it, $mode = RIT_SELF_FIRST, $depth_limit = -1)
{
parent::__construct($it, $mode);
$this->depth_limit = $depth_limit;
}
public function next ()
{
parent::next();
if ($this->getDepth() == $this->depth_limit)
{
while ($this->getSubIterator()->valid())
$this->getSubIterator()->next();
parent::next();
}
}
}
?>
Then you can try this:
<?php
class DirectoriesOnlyIterator extends FilterIterator implements RecursiveIterator
{
public function __construct ($path)
{
parent::__construct(new RecursiveDirectoryIterator($path));
}
public function accept()
{
return $this->getInnerIterator()->hasChildren();
}
public function hasChildren ()
{
return $this->getInnerIterator()->hasChildren();
}
public function getChildren ()
{
return new self($this->getInnerIterator()->getPathname());
}
}
$it = new LimitRecursiveIteratorIterator(new DirectoriesOnlyIterator('c:'), RIT_SELF_FIRST, 2);
foreach ($it as $key => $value)
{
echo str_repeat(' ', $it->getDepth()) . "$value\n";
}
?>
This is considerably faster than using just the RecursiveIteratorIterator and ignoring yourself in the foreach loop the values for depth > limit (i.e. if($it->getDepth() > $limit) continue;). that is because the class will still parse everything up to the last depth level of every head node.
You can then play and display nice trees (might need a while() loop or the CachingRecursiveIterator to detect end nodes/leafs). There is already an example provided by Marcus in the ext/spl/examples dir i mentioned above.
Happy SPL-ing :),
Bogdan
P.S. I think some of the classes should call rewind() at instantiation time ... If you try to put a Caching* object in a foreach loop you will lose the first/last element. Instead, you should call rewind() and then go with a while($cit->valid()) loop and using current() and key() inside it.