個人ブログ

インフラ、アプリケーションまわり

lsコマンドの機能を、LaravelとPHPで実装してみた ver.1

下記記事を読んで、bashコマンドと同じ機能を実現する練習をしようと思いました。

まずは、記事にも書かれているbashのlsコマンドでやってみます。

qiita.com

そもそもlsコマンドって?

lsコマンドの使い方と覚えたい15のオプション【Linuxコマンド集】

この辺りを参考にしてみてください。

今いるディレクトリ(or 指定したディレクトリ)に存在するファイルやフォルダをずらっと一覧表示してくれるあれです。

さっそく実装

実現したい機能としては、以下の通りです。

  • ディレクトリを指定した場合、そのディレクトリのファイル・フォルダを表示
  • ディレクトリを指定しなかった場合、カレントディレクトリ(今いる場所)のファイル・フォルダを一覧表示
  • 指定したディレクトリにファイルが存在しなかった場合は「指定のパスにファイルは存在しません」というメッセージを出力し、処理を中断

コンソールから自作のコマンドを叩くために、今回はLaravelのArtisanコンソールの機能を使いました。

Artisanコンソール 5.5 Laravel

下記コマンドを叩くと、新しいコマンドクラスが自動で生成される優れものです。

php artisan make:command LsCommand

下記記述により、コマンドからディレクトリのパスを指定できるようになります。

protected $signature = 'dir:get
                        {path? : 表示させたいパスを入力してください}';

protected $description = 'lsコマンドをLaravelに書き換えています';

処理の本体

コマンド実行時に呼び出されるのは、すでに記述されているhandleメソッドです。 この中に、行いたい処理の本体を記述していきます。

一旦今回は、PHPのDirectoryクラスを用いて実装していきます。Directoryクラスについては、下記のマニュアルに詳細が記載されています。

上記を参考に、以下を記述。

    public function handle()
    {
        // 表示するpathを取得。入力がない場合はカレントディレクトリを返す。
        if ($this->argument('path')) {
            $path = $this->argument('path');
        } else {
            $path = '.';
        }

        // 不正なpathが入力された場合に、エラーを返す
        if (!is_dir($path)) {
            $this->error('指定のパスにファイルは存在しません');
            return;
        }

        // 実行
        // falseになるディレクトリ名("0"など)で処理を止めないために、一度$fileに値を格納した上で、falseと比較している
        try{
            $directry = dir($path);
            while (($file = $directry->read()) !== false) {
                if ($file != '.' && $file != '..') {
                    $this->line($file);
                }
            }
            $directry->close();
        } catch (Exception $e) {
            $this->error($e->getMessage());
        }
    }

try-catch文の中のネストが深くなってしまっていますね。この辺りは改善する必要がありそうです。 あとは、エラーで返ってくる返り値についても、深く考えずに!を使って書いてしまっているので、ここも要確認ですね。

結果

実行コマンド

php artisan dir:get hoge
php artisan dir:get 
php artisan dir:get /

上記コマンドを叩くと、指定したLaravelのディレクトリに存在するファイル・フォルダが出力されました。