Skip to content

Instantly share code, notes, and snippets.

@vrkansagara
Forked from ralphschindler/tree.php
Created October 25, 2017 14:06
Show Gist options
  • Save vrkansagara/ee6b86d488cc5d4ff2f499e1c6f24b4c to your computer and use it in GitHub Desktop.
Save vrkansagara/ee6b86d488cc5d4ff2f499e1c6f24b4c to your computer and use it in GitHub Desktop.
'tree' console command, in PHP.
#!/usr/bin/php
<?php
/**
* Because you want "tree", but cannot find the source code quick enough
* on the web to compile for OS.X or there is no suitable implementation
* on windows.
*/
// set error reporting
error_reporting(E_STRICT | E_ALL);
// handle command line arguments
$arg_count = $_SERVER['argc'];
if ($arg_count > 1 && $_SERVER['argv'][$arg_count-1]{0} != '-') {
$path = $_SERVER['argv'][$arg_count-1];
} else {
$path = getcwd();
}
$options = getopt('e::', array('exclude::'));
if (isset($path) && file_exists($path)) {
$path = realpath($path);
} else {
die('Could not find path: ' . $path . PHP_EOL);
}
// create the tree's RecursiveDirectoryIterator (and tree iterator)
$recursiveIterator = $treeIterator = new Tree_RecursiveDirectoryIterator($path);
// if we need to exclude anything, set the RDI to a Filter Iterator
// using the TreeIterator as the source to iterate
if (isset($options['exclude']) || isset($options['e'])) {
Tree_RecursiveFilterIterator::$pattern = (isset($options['e'])) ? $options['e'] : $options['exclude'];
$recursiveIterator = new Tree_RecursiveFilterIterator($treeIterator);
}
// pass the target iterator to a iteratoriterator
foreach (new Tree_RecursiveIteratorIterator($recursiveIterator) as $item) {
echo $item . PHP_EOL;
}
/**
* Class to handle the iteration of the filesystem
*/
class Tree_RecursiveDirectoryIterator extends RecursiveDirectoryIterator
{
public function current()
{
return $this->getFilename();
}
}
/**
* Class to handle the filtering of items inside a RecrusiveIterator
*/
class Tree_RecursiveFilterIterator extends RecursiveFilterIterator
{
public static $pattern = null;
public function accept()
{
$regex = '#^' . self::$pattern . '#';
if ($this->isDir() && preg_match($regex, $this->current() . DIRECTORY_SEPARATOR)) {
return false;
}
return true;
}
}
/**
* Class to handle the actual iteration of the nodes.
*/
class Tree_RecursiveIteratorIterator extends RecursiveIteratorIterator
{
function __construct($treeRecursiveIterator)
{
parent::__construct(
new RecursiveCachingIterator(
$treeRecursiveIterator,
CachingIterator::CALL_TOSTRING|CachingIterator::CATCH_GET_CHILD
),
parent::SELF_FIRST
);
}
function current()
{
$tree = '';
for ($l=0; $l < $this->getDepth(); $l++) {
$tree .= $this->getSubIterator($l)->hasNext() ? '| ' : ' ';
}
return $tree
. ($this->getSubIterator($l)->hasNext() ? '|- ' : '`- ')
. $this->getSubIterator($l)->__toString();
}
function __call($func, $params)
{
return call_user_func_array(array($this->getSubIterator(), $func), $params);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment