Вы можете продлить RecursiveArrayIterator
, чтобы получить вид RecursiveDirectoryIterator
но для виртуальной файловой системы:
class RecursiveVirtualDirectoryIterator extends RecursiveArrayIterator
{
private $files;
public function __construct($parentId, $array = [], $flags = 0)
{
$this->files = $array;
parent::__construct(
$this->getFilesByParentId($parentId),
$flags
);
}
private $children;
public function hasChildren()
{
$file = $this->current();
if ($file['is_file']) {
return false;
}
$this->children = $this->getFilesByParentId($file['id']);
return !empty($this->children);
}
private function getFilesByParentId($id)
{
return array_filter($this->files, function ($file) use ($id) {
return $file['parent_id'] === $id;
});
}
public function getChildren()
{
$file = $this->current();
return new static(
$file['id'],
$this->children,
$this->getFlags()
);
}
}
Затем вы можете итерации по вашей возвращаемый массив из баз данных с использованием RecursiveIteratorIterator
и подсчета файлов для, скажем, вершинных папок:
$iterator = new RecursiveIteratorIterator(
new RecursiveVirtualDirectoryIterator(0, $files),
RecursiveIteratorIterator::SELF_FIRST
);
$currentDirectoryName = null;
$filesCount = [];
foreach ($iterator as $file) {
if ($iterator->getDepth() === 0 && !$file['is_file']) {
$currentDirectoryName = $file['name'];
$filesCount[$currentDirectoryName] = 0;
continue;
}
$filesCount[$currentDirectoryName] += 1;
}
Это working demo.
В то время как Standard PHP Library (SPL) плохо документирован, он содержит много полезных вещей, которые избавляют вас от повторного использования колеса снова и снова.
Пробовал что-нибудь еще? – Xorifelse
рекурсивный итератор каталогов или какая-либо другая рекурсивная функция? – Rasclatt
Нет, я не знаю, как его запустить. –