Laravel - 筆記:在 Migration 的過程中使用進度條 (ProgressBar) 顯示更新進度

零、背景

建立 Laravel Migration 時,有時候必須要根據現有資料庫中的資料逐筆更新,像是資料庫欄位轉移、變換等等的,當資料庫數據數量不多時,這樣的更新可能一下就完成了,但如果資料庫的資料很多時,會發現執行 php artisan migrate 時,會出現「等待該 migration 執行,但卻不知道目前執行狀況」的情境。

這時候如果這個資料庫更新,可以加上「進度條」呈現,就可以讓維運人員可以得到回應,相對了解當下的狀況,進而做出更好的狀態判斷。

那麼,該怎麼在 Laravel Migration 的過程中加上進度條 (Progress Bar) 呢?

進度條

一、在 migration 中使用進度條

環境版本

  • PHP 7.4
  • Laravel 8.5
  • Symfony 5.2

範例原始碼

如下為完整的範例原始碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
use Illuminate\Database\Migrations\Migration;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Output\ConsoleOutput;

class SomeMigrate extends Migration
{
public function up()
{
$count = 155;

$output = new ConsoleOutput();
$progressBar = new ProgressBar($output, $count);
$progressBar->start();

$i = 0;
while ($i < $count) {
// do something
usleep(5000);

$i++;
$progressBar->advance();
}

$progressBar->finish();
$output->write(PHP_EOL);
}
}

二、原始碼說明:

1. Line 11-12

1
2
$output = new ConsoleOutput();
$progressBar = new ProgressBar($output, $count);

在原始碼中的 Line 11-12 行使用了兩個 Symfony Framework 的工具,分別是 ConsoleOutput 以及 ProgressBar

在 Line 11 中 new ConsoleOutput() 在取得 CLI Console 畫面輸出的資源,而 Line 12 的 new ProgressBar($output, $count) 則是在畫面輸出的資源上,建立一個進度條物件,並且宣告這個物件預計會有 $count 個「步驟」。

另外 ProgressBar 這個物件還提供了第三個參數 $minSecondsBetweenRedraws 預設為 1/25 秒(0.25秒),如果遇到需要調整進度更新速度的情境,可以透過第三個參數做調整。

2. Line 13, 21, 24

1
2
3
$progressBar->start();
$progressBar->advance();
$progressBar->finish();

這三行分別是進度條的「開始」、「前進」及「結束」:

  • $progressBar->start() 進度條開始。

進度條開始呈現,這邊可以再次的設定這個進度條步驟總數,預設為 null 也就是沿用 ProgressBar 宣告時的進度步驟數,開始後 ProgressBar 本身的 timer 即開始作用,並在 Console 畫面上呈現進度條。

  • $progressBar->advance() 進度條步驟前進

讓進度前進並呈現在畫面上。預設為增加一個步驟,也可以透過參數調整,如 $progressBar->advance(4) 就是前進四個步驟。

  • $progressBar->finish() 進度條完成

完成整個進度條進度。就算目前進度尚未達到設定的最大值,依然直接呈現進度完成 100% 並且結束整個進度條。

3. Line 25

1
$output->write(PHP_EOL);

讓進度條完成後可以換到下一行繼續顯示。如果沒有在 ConsoleOutput 輸出一個換行字元,則會發現後續的 Migrated: SomeMigrate 換接續在進度條後面直接輸出。如下圖:

未輸出換行則會造成下一行輸出直接接續在進度條之後

三、總結

在 Symfony 提供的 Progress Bar 元件中,其實還有更多不一樣的用法,如自訂輸出格式,可以做出各種華麗的進度顯示,也可以同時呈現多條進度條,但對於一般的資料庫更新來說,預設值都還算夠用,有興趣也可以參考 Symfony 提供的 Progress Bar 文件 看更進階的使用方法。

四、參考連結

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器