Progress Bar

When executing longer-running commands, it may be helpful to show progress information, which updates as your command runs:

実行時間の長いコマンドを実行するときは、コマンドの実行時に更新される進捗情報を表示すると役立つ場合があります。

To display progress details, use the ProgressBar, pass it a total number of units, and advance the progress as the command executes:

進行状況の詳細を表示するには、ProgressBar を使用し、ユニットの総数を渡し、コマンドの実行に従って進行状況を進めます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
use Symfony\Component\Console\Helper\ProgressBar;

// creates a new progress bar (50 units)
$progressBar = new ProgressBar($output, 50);

// starts and displays the progress bar
$progressBar->start();

$i = 0;
while ($i++ < 50) {
    // ... do some work

    // advances the progress bar 1 unit
    $progressBar->advance();

    // you can also advance the progress bar by more than 1 unit
    // $progressBar->advance(3);
}

// ensures that the progress bar is at 100%
$progressBar->finish();

Tip

ヒント

You can also regress the progress bar (i.e. step backwards) by calling $progress->advance() with a negative value. For example, if you call $progress->advance(-2) then it will regress the progress bar 2 steps.

負の値で $progress->advance() を呼び出すことで、プログレス バーを後退させる (つまり、後ろに進める) こともできます。たとえば、$progress->advance(-2) を呼び出すと、プログレス バーが 2 ステップ後退します。

Instead of advancing the bar by a number of steps (with the advance() method), you can also set the current progress by calling the setProgress() method.

(advance() メソッドを使用して) いくつかのステップでバーを進める代わりに、setProgress() メソッドを呼び出して現在の進行状況を設定することもできます。

If you are resuming long-standing tasks, it's useful to start drawing the progress bar at a certain point. Use the second optional argument of start() to set that starting point:

長期にわたるタスクを再開する場合は、特定の時点で進行状況バーの描画を開始すると便利です。 start() の 2 番目のオプション引数を使用して、その開始点を設定します。
1
2
3
4
5
6
7
use Symfony\Component\Console\Helper\ProgressBar;

// creates a new progress bar (100 units)
$progressBar = new ProgressBar($output, 100);

// displays the progress bar starting at 25 completed units
$progressBar->start(null, 25);

6.2

6.2

The option to start a progress bar at a certain point was introduced in Symfony 6.2.

特定の時点で進行状況バーを開始するオプションは、Symfony 6.2 で導入されました。

Tip

ヒント

If your platform doesn't support ANSI codes, updates to the progress bar are added as new lines. To prevent the output from being flooded, use the minSecondsBetweenRedraws() method to limit the number of redraws and the setRedrawFrequency() method to redraw every N iterations. By default, redraw frequency is 100ms or 10% of your max.

プラットフォームが ANSI コードをサポートしていない場合、進行状況バーへの更新は新しい行として追加されます。出力があふれないようにするには、minSecondsBetweenRedraws() メソッドを使用して再描画の回数を制限し、setRedrawFrequency() メソッドを使用して N 回の繰り返しごとに再描画します。デフォルトでは、再描画頻度は 100ms または最大値の 10% です。

If you don't know the exact number of steps in advance, set it to a reasonable value and then call the setMaxSteps() method to update it as needed:

正確なステップ数が事前にわからない場合は、適切な値に設定してから、必要に応じて setMaxSteps() メソッドを呼び出して更新します。
1
2
3
4
5
// start with a 50 units progressbar
$progressBar = new ProgressBar($output, 50);

// a complex task has just been created: increase the progressbar to 200 units
$progressBar->setMaxSteps(200);

Another solution is to omit the steps argument when creating the ProgressBar instance:

もう 1 つの解決策は、ProgressBar インスタンスを作成するときに steps 引数を省略することです。
1
$progressBar = new ProgressBar($output);

The progress will then be displayed as a throbber:

進行状況は、throbber として表示されます。
1
2
3
4
5
6
7
8
9
# no max steps (displays it like a throbber)
    0 [>---------------------------]
    5 [----->----------------------]
    5 [============================]

# max steps defined
 0/3 [>---------------------------]   0%
 1/3 [=========>------------------]  33%
 3/3 [============================] 100%

Whenever your task is finished, don't forget to call finish() to ensure that the progress bar display is refreshed with a 100% completion.

タスクが終了したら、finish() を呼び出すことを忘れないでください。プログレス バーの表示が 100% 完了したことを確認するために更新されます。

Note

ノート

If you want to output something while the progress bar is running, call clear() first. After you're done, call display() to show the progress bar again.

プログレスバーの実行中に何かを出力したい場合は、最初に clear() を呼び出します。完了したら、display() を呼び出してプログレスバーを再度表示します。

If the progress information is stored in an iterable variable (such as an array or a PHP generator) you can use the iterate() method, which starts, advances and finishes the progress bar automatically:

進行状況情報が反復可能な変数 (配列や PHP ジェネレーターなど) に格納されている場合は、進行状況バーを自動的に開始、進め、終了する iterate() メソッドを使用できます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
use Symfony\Component\Console\Helper\ProgressBar;

$progressBar = new ProgressBar($output);

// $iterable can be array
$iterable = [1, 2];
foreach ($progressBar->iterate($iterable) as $value) {
    // ... do some work
}

// or a generator
function iterable() { yield 1; yield 2; ... };
foreach ($progressBar->iterate(iterable()) as $value) {
    // ... do some work
}

The previous code will output:

前のコードは次を出力します。
1
2
3
0/2 [>---------------------------]   0%
1/2 [==============>-------------]  50%
2/2 [============================] 100%

Customizing the Progress Bar

Built-in Formats

By default, the information rendered on a progress bar depends on the current level of verbosity of the OutputInterface instance:

デフォルトでは、プログレス バーに表示される情報は、OutputInterface インスタンスの現在の詳細レベルによって異なります。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# OutputInterface::VERBOSITY_NORMAL (CLI with no verbosity flag)
 0/3 [>---------------------------]   0%
 1/3 [=========>------------------]  33%
 3/3 [============================] 100%

# OutputInterface::VERBOSITY_VERBOSE (-v)
 0/3 [>---------------------------]   0%  1 sec
 1/3 [=========>------------------]  33%  1 sec
 3/3 [============================] 100%  1 sec

# OutputInterface::VERBOSITY_VERY_VERBOSE (-vv)
 0/3 [>---------------------------]   0%  1 sec/1 sec
 1/3 [=========>------------------]  33%  1 sec/1 sec
 3/3 [============================] 100%  1 sec/1 sec

# OutputInterface::VERBOSITY_DEBUG (-vvv)
 0/3 [>---------------------------]   0%  1 sec/1 sec  1.0 MB
 1/3 [=========>------------------]  33%  1 sec/1 sec  1.0 MB
 3/3 [============================] 100%  1 sec/1 sec  1.0 MB

Note

ノート

If you call a command with the quiet flag (-q), the progress bar won't be displayed.

quiet フラグ (-q) を指定してコマンドを呼び出した場合、進行状況バーは表示されません。

Instead of relying on the verbosity mode of the current command, you can also force a format via setFormat():

現在のコマンドの冗長モードに依存する代わりに、setFormat() を使用してフォーマットを強制することもできます。
1
$progressBar->setFormat('verbose');

The built-in formats are the following:

組み込みの形式は次のとおりです。
  • normal
    正常
  • verbose
    詳細
  • very_verbose
    very_verbose
  • debug
    デバッグ

If you don't set the number of steps for your progress bar, use the _nomax variants:

プログレス バーのステップ数を設定しない場合は、_nomaxvariants を使用します。
  • normal_nomax
    normal_nomax
  • verbose_nomax
    verbose_nomax
  • very_verbose_nomax
    very_verbose_nomax
  • debug_nomax
    debug_nomax

Custom Formats

Instead of using the built-in formats, you can also set your own:

組み込みの形式を使用する代わりに、独自の形式を設定することもできます。
1
$progressBar->setFormat('%bar%');

This sets the format to only display the progress bar itself:

これは、進行状況バー自体のみを表示するようにフォーマットを設定します。
1
2
3
>---------------------------
=========>------------------
============================

A progress bar format is a string that contains specific placeholders (a name enclosed with the % character); the placeholders are replaced based on the current progress of the bar. Here is a list of the built-in placeholders:

プログレス バーの形式は、特定のプレースホルダー (% 文字で囲まれた名前) を含む文字列です。プレースホルダーはバーの現在の進行状況に基づいて置き換えられます。組み込みのプレースホルダーのリストは次のとおりです。
  • current: The current step;
    current: 現在のステップ。
  • max: The maximum number of steps (or 0 if no max is defined);
    max: ステップの最大数 (最大値が定義されていない場合は 0)。
  • bar: The bar itself;
    bar: バー自体。
  • percent: The percentage of completion (not available if no max is defined);
    percent: 完了率 (最大値が定義されていない場合は使用できません)。
  • elapsed: The time elapsed since the start of the progress bar;
    経過: プログレス バーの開始からの経過時間。
  • remaining: The remaining time to complete the task (not available if no max is defined);
    残り: タスクを完了するための残り時間 (最大値が定義されていない場合は使用できません)。
  • estimated: The estimated time to complete the task (not available if no max is defined);
    推定: タスクを完了するための推定時間 (最大値が定義されていない場合は利用できません)。
  • memory: The current memory usage;
    メモリ: 現在のメモリ使用量;
  • message: used to display arbitrary messages in the progress bar (as explained later).
    message: プログレス バーに任意のメッセージを表示するために使用されます (後で説明します)。

For instance, here is how you could set the format to be the same as the debug one:

たとえば、フォーマットをデバッグ フォーマットと同じに設定する方法は次のとおりです。
1
$progressBar->setFormat(' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s% %memory:6s%');

Notice the :6s part added to some placeholders? That's how you can tweak the appearance of the bar (formatting and alignment). The part after the colon (:) is used to set the sprintf format of the string.

一部のプレースホルダーに :6s の部分が追加されていることに注意してください。このようにして、バーの外観を微調整できます (書式設定と配置)。コロン (:) の後の部分は、文字列の sprintf 形式を設定するために使用されます。

Instead of setting the format for a given instance of a progress bar, you can also define global formats:

プログレス バーの特定のインスタンスのフォーマットを設定する代わりに、グローバル フォーマットを定義することもできます。
1
2
3
4
ProgressBar::setFormatDefinition('minimal', 'Progress: %percent%%');

$progressBar = new ProgressBar($output, 3);
$progressBar->setFormat('minimal');

This code defines a new minimal format that you can then use for your progress bars:

このコードは、プログレス バーに使用できる新しい最小限の形式を定義します。
1
2
3
Progress: 0%
Progress: 33%
Progress: 100%

Tip

ヒント

It is almost always better to redefine built-in formats instead of creating new ones as that allows the display to automatically vary based on the verbosity flag of the command.

コマンドの詳細フラグに基づいて表示を自動的に変更できるようにするため、新しい形式を作成するよりも、組み込み形式を再定義する方がほとんどの場合優れています。

When defining a new style that contains placeholders that are only available when the maximum number of steps is known, you should create a _nomax variant:

最大ステップ数がわかっている場合にのみ使用可能なプレースホルダーを含む新しいスタイルを定義する場合は、_nomaxvariant を作成する必要があります。
1
2
3
4
5
ProgressBar::setFormatDefinition('minimal', '%percent%% %remaining%');
ProgressBar::setFormatDefinition('minimal_nomax', '%percent%%');

$progressBar = new ProgressBar($output);
$progressBar->setFormat('minimal');

When displaying the progress bar, the format will automatically be set to minimal_nomax if the bar does not have a maximum number of steps like in the example above.

プログレス バーを表示するとき、上記の例のようにバーに最大ステップ数がない場合、フォーマットは自動的に minimal_nomax に設定されます。

Tip

ヒント

A format can contain any valid ANSI codes and can also use the Symfony-specific way to set colors:

フォーマットには有効な ANSI コードを含めることができ、Symfony 固有の方法を使用して色を設定することもできます。
1
2
3
4
ProgressBar::setFormatDefinition(
    'minimal',
    '<info>%percent%</info>\033[32m%\033[0m <fg=white;bg=blue>%remaining%</>'
);

Note

ノート

A format can span more than one line; that's very useful when you want to display more contextual information alongside the progress bar (see the example at the beginning of this article).

フォーマットは複数行にまたがることができます。これは、プログレス バーの横にコンテキスト情報を表示したい場合に非常に便利です (この記事の最初の例を参照してください)。

Bar Settings

Among the placeholders, bar is a bit special as all the characters used to display it can be customized:

プレースホルダーの中で、bar は、表示に使用されるすべての文字をカスタマイズできるため、少し特殊です。
1
2
3
4
5
6
7
8
9
10
11
// the finished part of the bar
$progressBar->setBarCharacter('<comment>=</comment>');

// the unfinished part of the bar
$progressBar->setEmptyBarCharacter(' ');

// the progress character
$progressBar->setProgressCharacter('|');

// the bar width
$progressBar->setBarWidth(50);

Caution

注意

For performance reasons, Symfony redraws the screen once every 100ms. If this is too fast or too slow for your application, use the methods minSecondsBetweenRedraws() and maxSecondsBetweenRedraws():

パフォーマンス上の理由から、Symfony は 100 ミリ秒ごとに画面を再描画します。これがアプリケーションにとって速すぎるか遅すぎる場合は、メソッド minSecondsBetweenRedraws() および maxSecondsBetweenRedraws() を使用します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$progressBar = new ProgressBar($output, 50000);
$progressBar->start();

// this redraws the screen every 100 iterations, but sets additional limits:
// don't redraw slower than 200ms (0.2) or faster than 100ms (0.1)
$progressBar->setRedrawFrequency(100);
$progressBar->maxSecondsBetweenRedraws(0.2);
$progressBar->minSecondsBetweenRedraws(0.1);

$i = 0;
while ($i++ < 50000) {
    // ... do some work

    $progressBar->advance();
}

Custom Placeholders

If you want to display some information that depends on the progress bar display that are not available in the list of built-in placeholders, you can create your own. Let's see how you can create a remaining_steps placeholder that displays the number of remaining steps:

プログレス バー表示に依存する、組み込みのプレースホルダーのリストでは利用できない情報を表示したい場合は、独自のプレースホルダーを作成できます。残りのステップ数を表示する、remaining_steps プレースホルダーを作成する方法を見てみましょう。
1
2
3
4
5
6
ProgressBar::setPlaceholderFormatterDefinition(
    'remaining_steps',
    function (ProgressBar $progressBar, OutputInterface $output) {
        return $progressBar->getMaxSteps() - $progressBar->getProgress();
    }
);

Custom Messages

Progress bars define a placeholder called message to display arbitrary messages. However, none of the built-in formats include that placeholder, so before displaying these messages, you must define your own custom format:

プログレス バーは、メッセージと呼ばれるプレースホルダーを定義して、任意のメッセージを表示します。ただし、組み込みの形式にはそのプレースホルダーが含まれていないため、これらのメッセージを表示する前に、独自のカスタム形式を定義する必要があります。
1
2
3
4
ProgressBar::setFormatDefinition('custom', ' %current%/%max% -- %message%');

$progressBar = new ProgressBar($output, 100);
$progressBar->setFormat('custom');

Now, use the setMessage() method to set the value of the %message% placeholder before displaying the progress bar:

ここで、進行状況バーを表示する前に、setMessage() メソッドを使用して %message%placeholder の値を設定します。
1
2
3
4
5
6
7
8
// ...
$progressBar->setMessage('Start');
$progressBar->start();
// 0/100 -- Start

$progressBar->setMessage('Task is in progress...');
$progressBar->advance();
// 1/100 -- Task is in progress...

Messages can be combined with custom placeholders too. In this example, the progress bar uses the %message% and %filename% placeholders:

メッセージは、カスタム プレースホルダーと組み合わせることもできます。この例では、進行状況バーは %message% および %filename% プレースホルダーを使用しています。
1
2
3
4
ProgressBar::setFormatDefinition('custom', ' %current%/%max% -- %message% (%filename%)');

$progressBar = new ProgressBar($output, 100);
$progressBar->setFormat('custom');

The setMessage() method accepts a second optional argument to set the value of the custom placeholders:

setMessage() メソッドは、カスタム プレースホルダーの値を設定するための 2 番目のオプション引数を受け入れます。
1
2
3
4
5
6
7
8
// ...
// $files = ['client-001/invoices.xml', '...'];
foreach ($files as $filename) {
    $progressBar->setMessage('Importing invoices...');
    $progressBar->setMessage($filename, 'filename');
    $progressBar->advance();
    // 2/100 -- Importing invoices... (client-001/invoices.xml)
}

Displaying Multiple Progress Bars

When using Console output sections it's possible to display multiple progress bars at the same time and change their progress independently:

コンソール出力セクションを使用すると、複数の進行状況バーを同時に表示して、進行状況を個別に変更できます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$section1 = $output->section();
$section2 = $output->section();

$progress1 = new ProgressBar($section1);
$progress2 = new ProgressBar($section2);

$progress1->start(100);
$progress2->start(100);

$i = 0;
while (++$i < 100) {
    $progress1->advance();

    if ($i % 2 === 0) {
        $progress2->advance(4);
    }

    usleep(50000);
}

After a couple of iterations, the output in the terminal will look like this:

数回繰り返した後、ターミナルの出力は次のようになります。
1
2
34/100 [=========>------------------]  34%
68/100 [===================>--------]  68%