Если вам нужно только имя текущей папки и получить плоский массив взамен, вы можете extend
a RecursiveFilterIterator
и просто собрать стек во время RunTime при проверке, хотите ли вы accept()
его. Внутри метода accept()
вы, конечно, пропускаете все, к которым не подключены дочерние итераторы, поэтому вы не будете без необходимости проходить ненужные части.
class DirectoryStackIterator extends RecursiveFilterIterator
{
public static $stack = [];
public function __construct( FilesystemIterator $iterator )
{
parent::__construct( $iterator );
}
public function getStack()
{
return self::$stack;
}
public function accept()
{
if ( $this->hasChildren() )
{
foreach ( $this->getChildren() as $c )
{
$dir = basename( $c->getPath() );
$c->isDir()
&& ! in_array( $dir, self::$stack )
AND self::$stack[] = $dir;
}
}
return $this->hasChildren();
}
}
Это позволяет довольно легко определить, что именно вы хотите получить взамен. $c
является экземпляром SPLFileInfo
, поэтому просто обратитесь к нему.
$iterator = new DirectoryStackIterator(
new RecursiveDirectoryIterator(
__DIR__,
FilesystemIterator::FOLLOW_SYMLINKS
| FilesystemIterator::SKIP_DOTS
)
);
Затем мы присоединяем RecursiveDirectoryIterator
(который расширяет FilesystemIterator
, который затем расширяет DirectoryIterator
- чтобы увидеть, какие методы вы получили) и SKIP_DOTS
, но следуйте символическим ссылкам. Удалите последний, если вы этого не хотите.
Наконец, мы просто проходим через итераторы итераторов, фактически ничего не делая. Не забывайте использовать точку с запятой (;
) в конце, чтобы ничего не вызывать на следующей строке в случае аварии.
foreach ( $iterator as $dir );
Собрать наш пользовательский стек довольно просто:
var_dump( $iterator->getStack() );