I wanted to play around with some of PHP's iterators and managed to get a solid (from my understanding) build going. My goal was to iterate inside of a parent folder and get 2 nodes down; building a hierarchical tree array during the process. Obviously, I could do this fairly easy using glob and a couple of nested loops but I want to use Spl classes to accomplish this.
All that out of the way, I've played around with SplHeap and SplObjectStore to hierarchy and failed. What's messing with my noodle is my normal methods of recursion are failing (out-of-memory errors) and my one success falls with a recursive method that loops over each node, adding to an array. The problem with that is it ignores the setMaxDepth() method and goes through all of the children. I thought about setting a $var++ to increment through the loop, limiting to limit the nodes but I don't believe that's the "right way".
Anywho, code (sorry for any orphaned code if any - just ignore it)...
<?php
namespace Tree;
use RecursiveFilterIterator,
RecursiveDirectoryIterator,
RecursiveIteratorIterator;
class Filter extends RecursiveFilterIterator {
public static $FILTERS = array(
'.git', '.gitattributes', '.gitignore', 'index.php'
);
public function accept() {
if (!$this->isDot() && !in_array($this->current()->getFilename(), self::$FILTERS))
return TRUE;
return FALSE;
}
}
class DirTree {
const MAX_DEPTH = 2;
private static $iterator;
private static $objectStore;
public function __construct() {
error_reporting(8191);
$path = realpath('./');
try {
$dirItr = new RecursiveDirectoryIterator($path);
$filterItr = new Filter($dirItr);
$objects = new RecursiveIteratorIterator($filterItr, RecursiveIteratorIterator::SELF_FIRST);
$objects->setMaxDepth(self::MAX_DEPTH);
echo '<pre>';
print_r($this->build_hierarchy($objects));
} catch(Exception $e) {
die($e->getMessage());
}
}
public function build_hierarchy($iterator){
$array = array();
foreach ($iterator as $fileinfo) {
if ($fileinfo->isDir()) {
// Directories and files have labels
$current = array(
'label' => $fileinfo->getFilename()
);
// Only directories have children
if ($fileinfo->isDir()) {
$current['children'] = $this->build_hierarchy($iterator->getChildren());
}
// Append the current item to this level
$array[] = $current;
}
}
return $array;
}
}
$d = new DirTree;