14
13

More than 5 years have passed since last update.

RecursiveTreeIteratorでtreeコマンドを実装

Last updated at Posted at 2012-12-26

treeコマンドだって簡単に書ける、そうPHPならね。
Iteratorは拡張性を確保する手段として面白いです。
http://jp2.php.net/manual/ja/class.recursivetreeiterator.php

オプションのパースが面倒だったので-a(dotfileも表示) -d(ディレクトリだけ表示) -L(再帰レベル指定) しか対応してないです。
実行権限を与えて./tree.phpなどのように実行すると、現在のディレクトリがアスキーアートでツリー表示されます。

tree.php
#!/usr/bin/env php
<?php
/**
 * treeコマンドのPHP5.3による実装例。
 */
namespace Tree;

//iterator類は名前が長いので短縮
use RecursiveDirectoryIterator as RDI,
    RecursiveFilterIterator as RFI,
    RecursiveTreeIterator as RTI;

$opt = getopt('adL:');

$di = new RDI('.');

// -a で"."から始まるファイルも表示。 --------------
// 通常は"."をフィルタする
if (!isset($opt['a'])) {
    $di = new DotFilter($di);
}
class DotFilter extends RFI {
    function accept() {
        $fname = $this->current()->getFilename();
        return $fname[0] !== '.';
    }
}

// -d で ディレクトリのみにフィルタ -----------------
if (isset($opt['d'])) {
    $di = new \ParentIterator($di);
}

$rti = new RTI($di, RTI::BYPASS_CURRENT);
// デザインを少し変更。Unix風
$rti->setPrefixPart(RTI::PREFIX_END_LAST, '`-');
$rti->setPrefixPart(RTI::PREFIX_RIGHT, '- ');

// -L n で深さを指定
if (isset($opt['L'])) {
    $rti->setMaxDepth((int)$opt['L'] - 1);
}

foreach ($rti as $file) {
    echo $rti->getPrefix();
    echo $file->getFilename();
    echo PHP_EOL;
}

大事なのはforeachたった1つでこれが実現できていることですね。

14
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
13