note 44842 deleted from ref.spl by salathe

From: Date: Tue, 16 Feb 2010 10:59:23 +0000
Subject: note 44842 deleted from ref.spl by salathe
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-166002@lists.php.net to get a copy of this message
Note Submitter: mastabog at hotmail dot com Reason: 0 ---- 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 /** * Limit Depth RecursiveIteratorIterator class * */ class LimitRecursiveIteratorIterator extends RecursiveIteratorIterator { protected $depth_limit; /** * No depth limit by default * **/ public function __construct (Iterator $it, $mode = RIT_SELF_FIRST, $depth_limit = -1) { parent::__construct($it, $mode); $this->depth_limit = $depth_limit; } /** * After the call to next() if depth is bigger than limit then * just skip all subIterators for that depth until depth end. * **/ 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 /** * Directories only filter iterator class * */ 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); // list all dirs and 1st subdir of the c: drive (might take a while depending on how many you have) 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.

« previous php.notes (#166002) next »