Laravelでコマンドライン処理を行う

# 目次
Laravelの記事一覧は下記
[PHPフレームワークLaravelの使い方](https://qiita.com/toontoon/items/c4d0371e504c37f6576e)

# Laravelバージョン
動作確認はLaravel Framework 7.19.1で行っています

# 前提条件
[eclipseでLaravel開発環境を構築する。デバッグでブレークポイントをつけて止める。(WindowsもVagrantもdockerも)](https://qiita.com/toontoon/items/76fa7f8845b20776077c)
本記事は上記が完了している前提で書かれています
プロジェクトの作成もapacheの設定も上記で行っています

# Commandクラス作成
コマンドラインで
`cd sample`
`php artisan make:command SampleCommand`
xdebugの設定をしているとeclipseが実行していいですかというプロンプトを出すのでOKを押します
eclipseプロジェクトを右クリック→リフレッシュ
/sample/app/Console/Commands/SampleCommand.phpが現れます

# Commandクラス修正
さきほど作成したSampleCommand.phpを下記に修正します

```SampleCommand.php
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class SampleCommand extends Command
{
    protected $signature = 'sample:name1 {arg1} {arg2=val2} {arg3?} {--option1} {--option2=} {--option3=opVal3} {--option4=*}';

    protected $description = 'このプログラムの説明を書く';

    public function __construct()
    {
        parent::__construct();
    }

    public function handle()
    {
        $arg1 = $this->argument('arg1');
        $arg2 = $this->argument('arg2');
        $arg3 = $this->argument('arg3');
        $option1 = $this->option('option1');
        $option2 = $this->option('option2');
        $option3 = $this->option('option3');
        $option4 = $this->option('option4');

        $this->line('下記入力を受け付けました');
        $this->line('arg1:' . $arg1);
        $this->line('arg2:' . $arg2);
        $this->line('arg3:' . $arg3);
        $this->line('option1:' . $option1);
        $this->line('option2:' . $option2);
        $this->line('option3:' . $option3);
        $this->line('option4:' . var_export($option4, true));

        $in = $this->ask('何か入力してください');
        $this->line('下記入力を受け付けました');
        $this->line($in);

        $in = $this->secret('何か入力してください。この入力中はユーザーがタイプした値を表示しません');
        $this->line('下記入力を受け付けました');
        $this->line($in);

        if ($this->confirm('yかyesを入力するとtrueとして扱います')) {
            $this->line('true');
        } else {
            $this->line('false');
        }

        $in = $this->choice(
                  '選択入力。カンマ区切りで複数入力できます',
                  ['php', 'Laravel', 'apache', 'eclipse'], //選択肢
                  $defaultIndex = 1, // 何も選ばれなかった場合に返ってくる選択肢の要素
                  $maxAttempts = 2, // 最大選択可能個数
                  $allowMultipleSelections = true // 複数選択可ならtrueにする
            );
        $this->line('下記入力を受け付けました');
        $this->line(var_export($in, true));

        $this->line('テーブル出力');
        $head = ['col1', 'col2', 'col3', 'col4'];
        $body = [
            ['1-col1', '1-col2', '1-col3', '1-col4'],
            ['2-col1', '2-col2', '2-col3', '2-col4'],
            ['3-col1', '3-col2', '3-col3', '3-col4'],
        ];
        $this->table($head, $body);


        $this->line('プログレスバー出力');
        $bar = $this->output->createProgressBar(10); // プログレスバーを10の区切りで出力
        $bar->start();
        for ($i = 0; $i < 10; $i++) {
            sleep(1);
            $bar->advance();
        }
        $bar->finish();

        $this->line('');
        $this->error('エラー出力');

    }
}

```
`$signature`変数はこのコマンドの引数、オプションを定義します
ユーザーから入力してもらう引数とオプションはすべて波括弧で囲んで定義します
{arg1} 第1引数必須。プログラム内で`$this->argument('arg1')`で値を取得できる
{arg2=val2}  第2引数任意。入力されなかった場合、`$this->argument('arg2')`でval2が返る
{arg3?}  第3引数任意。デフォルト値無し
{--option1} オプション。option1オプションが指定されると`$this->option('option1')`でtrueが返る
{--option2=} オプション。コマンド実行時何か値を与えるオプション
{--option3=opVal3}  オプション。入力されなかった場合、`$this->option('option3')`でopVal3が返る
{--option4=*}　オプション。コマンド実行時何か値を与えるオプション。複数の値を渡すことができる。`$this->option('option4')`の結果は配列となる

`$description`変数はこのコマンドの説明です

handleメソッドは実際の処理です
コマンドライン処理が実行されるとhandleメソッドが実行されます
`$this->argument`は引数を取得できます
`$this->option`はオプションを取得できます
`$this->line`は文字列を出力できます
`$this->ask`はユーザーからの入力を待ちます
`$this->secret`はユーザーからの入力を待ちます。ただし、ユーザーのタイピングした値が表示されません。パスワード入力などに使います
`$this->confirm`はユーザーの入力によりbool値を返します
`$this->choice`はユーザーに選択肢から値を選択させます
`$this->table`はテーブル形式で表示されます
`$this->output->createProgressBar`の戻り値を使うことによってプログレスバーを表示できます
`$this->error`でエラー時の文字列出力ができます

# Commandクラス登録
作成したCommandクラスを呼び出せるようにLaravelに登録しましょう
 /sample/app/Console/Kernel.php修正

```Kernel.php
‥‥
    protected $commands = [
        Commands\SampleCommand::class
    ];

‥‥
```

Kernel.phpに定義されている$commands配列に先ほど作成したSampleCommandクラス名を追記します
これでコマンドラインで実行できるようになりました

# 動作確認
コマンドラインで
`cd sample`
`php artisan sample:name1 aaa bbb ccc --option1 --option2=eee --option3=fff --option4=ggg --option4=hhh`
先ほど作成したSampleCommandクラスの`$signature`変数に定義した通りにコマンドラインで実行します
xdebugの設定をしているとeclipseが実行していいですかというプロンプトを出すのでOKを押します

実行結果

```
下記入力を受け付けました
arg1:aaa
arg2:bbb
arg3:ccc
option1:1
option2:eee
option3:fff
option4:array (
  0 => 'ggg',
  1 => 'hhh',
)

 何か入力してください:
 > aaa

下記入力を受け付けました
aaa

 何か入力してください。この入力中はユーザーがタイプした値を表示しません:
 >

下記入力を受け付けました
bbb

 yかyesを入力するとtrueとして扱います (yes/no) [no]:
 > y

true

 選択入力。カンマ区切りで複数入力できます [Laravel]:
  [0] php
  [1] Laravel
  [2] apache
  [3] eclipse
 > 2,3

下記入力を受け付けました
array (
  0 => 'apache',
  1 => 'eclipse',
)
テーブル出力
+--------+--------+--------+--------+
| col1   | col2   | col3   | col4   |
+--------+--------+--------+--------+
| 1-col1 | 1-col2 | 1-col3 | 1-col4 |
| 2-col1 | 2-col2 | 2-col3 | 2-col4 |
| 3-col1 | 3-col2 | 3-col3 | 3-col4 |
+--------+--------+--------+--------+
プログレスバー出力
 10/10 [============================] 100%
エラー出力
```

実行できました