note 44842 added to ref.spl

From: Date: Tue, 17 Aug 2004 21:41:30 +0000
Subject: note 44842 added to ref.spl
Groups: php.notes 
Request: Send a blank email to php-notes+get-74836@lists.php.net to get a copy of this message
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. ---- Manual Page -- http://www.php.net/manual/en/ref.spl.php Edit -- http://master.php.net/manage/user-notes.php?action=edit+44842 Delete -- http://master.php.net/manage/user-notes.php?action=delete+44842&report=yes Reject -- http://master.php.net/manage/user-notes.php?action=reject+44842&report=yes Search -- http://master.php.net/manage/user-notes.php

« previous php.notes (#74836) next »