CLI Library?

CodeIgniter 的 CLI 庫,讓創建命令行交互腳本變得簡單。其中包括:

  • 為用戶提供更多信息
  • 在終端上打印彩色文本
  • Beeping (be nice!)
  • 在長任務中顯示進度條
  • 讓長文本行適應窗口

初始化類?

你不需要創建 CLI 庫的實例,因為它的所有方法都是靜態方法。你只需要確保你的控制器可以通過 use 聲明找到它:

<?php namespace App\Controllers;

use CodeIgniter\CLI\CLI;

class MyController extends \CodeIgniter\Controller
{
        . . .
}

首次加載該文件時,這個類會自動初始化。

獲取用戶輸入?

有時你需要詢問用戶更多的信息。他們可能沒有提供可選的命令行參數,或者腳本遇到了存在的文件,在覆寫前需要進行確認。 這時使用 prompt() 方法處理

你可以提供一個問題作為方法的第一個參數:

$color = CLI::prompt('What is your favorite color?');

你可以提供一個默認的答案作為方法的第二個參數。如果用戶沒有任何輸入,只是按下 Enter 鍵,則將使用該默認答案:

$color = CLI::prompt('What is your favorite color?', 'blue');

你可以向第二個參數傳入允許答案的數組,以限制可以接受的答案:

$overwrite = CLI::prompt('File exists. Overwrite?', ['y','n']);

最后你可以將驗證規則作為第三個參數,以限制輸入的答案:

$email = CLI::prompt('What is your email?', null, 'required|valid_email');

提供反饋?

write()

多個方法可以用來向用戶提供反饋。它可以像更新單個狀態一樣簡單,也可以包裝復雜的信息表到用戶終端。 其核心是 write() 方法,該方法將要輸出的字符串作為第一個參數:

CLI::write('The rain in Spain falls mainly on the plains.');

你可以輸入顏色名稱作為第二個參數來更改文本的顏色:

CLI::write('File created.', 'green');

你可以向第三個參數輸入顏色名稱來設置背景顏色。這可以用于按狀態區分消息,或使用其他顏色創建“標題”:

CLI::write('File overwritten.', 'light_red', 'dark_gray');

可以使用以下前景色:

  • black
  • dark_gray
  • blue
  • dark_blue
  • light_blue
  • green
  • light_green
  • cyan
  • light_cyan
  • red
  • light_red
  • purple
  • light_purple
  • light_yellow
  • yellow
  • light_gray
  • white

少數可以用作背景色:

  • black
  • blue
  • green
  • cyan
  • red
  • yellow
  • light_gray
  • magenta

print()

Print 方法的功能和 write 相同,不同的是它不會在行前或者行尾強制換行。它將信息打印到當前屏幕光標所在的位置上, 這讓你可以在不同的代碼位置,打印信息到屏幕的同一行上。當你顯示狀態,執行某些操作后在同一行打印 “Done” 時,這十分有用:

for ($i = 0; $i <= 10; $i++)
{
    CLI::print($i);
}

color()

write() 方法將單行文本打印到終端,并打印 EOL 標識符結尾。color() 方法以相同的方式處理文本,不同的是它不會在結尾打印 EOL 標識符。 這可以讓你在同一行創建多個輸出。更常見的用法是在 write() 方法內部使用,以在同一行中顯示不同顏色的文本:

CLI::write("fileA \t". CLI::color('/path/to/file', 'white'), 'yellow');

該示例將打印一行文本到終端。首先用黃色打印 fileA ,接著打印一個制表符,最后用白色打印 /path/to/file

error()

如果你需要輸出錯誤信息,則應該使用 error 方法。它會將淺紅色的文本寫入到 STDERR,而不是像 write()color() 一樣寫入到 STDOUT。 如果你使用腳本監視錯誤信息,這樣就可以只捕獲到實際的錯誤信息,不必從所有信息中進行篩選:

CLI::error('Cannot write to file: ' . $file);

wrap()

該方法將獲取一個字符串,并開始在當前行開始打印。它將會根據設置的長度對字符串進行包裝,每行只顯示設置的長度的內容。 他可以用來顯示帶有說明的顯示列表,避免過多內容顯示在一行內,影響閱讀:

CLI::color("task1\t", 'yellow');
CLI::wrap("Some long description goes here that might be longer than the current window.");

默認情況下,字符串將用終端寬度進行包裝。Windows 目前無法提供確定的窗口大小,所以默認使用 80 個字符。如果你希望將寬度設置的更短一些, 可以將最大行長度作為第二個參數傳遞。這將在最接近該長度的單詞處斷開字符,以避免破壞單詞:

// Wrap the text at max 20 characters wide
CLI::wrap($description, 20);

你會發現需要左邊需要一列顯示標題、文件或任務,而右邊需要一列顯示文本和他的說明。默認情況下, 這將換行到窗口的左邊緣,即不允許信息按列排列。這時你可以用空格來填充第一行之后的每一行, 以便讓左側具有清晰的列邊緣:

// 確定所有標題的最大長度
// 確定左列的寬度
$maxlen = max(array_map('strlen', $titles));

for ($i=0; $i < count($titles); $i++)
{
        CLI::write(
                // 在行的左側列顯示標題
                $titles[$i] . '   ' .
                // 在行的右側列包裝信息
                // 與左側最寬的內容間隔三個寬度
                CLI::wrap($descriptions[$i], 40, $maxlen + 3)
        );
}

將創建以下內容:

task1a   Lorem Ipsum is simply dummy
           text of the printing and typesetting
           industry.
task1abc   Lorem Ipsum has been the industry's
           standard dummy text ever since the

newLine()

newLine() 方法向用戶顯示一個空行,它不需要任何參數:

CLI::newLine();

clearScreen()

你可以使用 clearScreen() 方法清除當前窗口。在多數的 Windows 系統中,它將插入 40 行空白行,因為 Windows 不支持該功能。 Windows 10 bash 因該能改變這點:

CLI::clearScreen();

showProgress()

如果你有一個長時間運行的任務,你希望讓用戶了解當前的執行進度,則可以使用 showProgress() 方法,它顯示以下內容:

[####......] 40% Complete

該行將設置為動態顯示,以獲得良好的展示效果。

將當前的步驟作為第一個參數傳入,并將總步驟作為第二個參數傳入。完成的百分比和顯示長度將根據該數字確認。當任務完成后,傳遞 false 作為第一個參數,進度條將被刪除:

$totalSteps = count($tasks);
$currStep   = 1;

foreach ($tasks as $task)
{
        CLI::showProgress($currStep++, $totalSteps);
        $task->run();
}

// Done, so erase it...
CLI::showProgress(false);

table()

$thead = ['ID', 'Title', 'Updated At', 'Active'];
$tbody = [
        [7, 'A great item title', '2017-11-15 10:35:02', 1],
        [8, 'Another great item title', '2017-11-16 13:46:54', 0]
];

CLI::table($tbody, $thead);
+----+--------------------------+---------------------+--------+
| ID | Title                    | Updated At          | Active |
+----+--------------------------+---------------------+--------+
| 7  | A great item title       | 2017-11-16 10:35:02 | 1      |
| 8  | Another great item title | 2017-11-16 13:46:54 | 0      |
+----+--------------------------+---------------------+--------+

wait()

等待一定的秒數。可以選擇顯示等待消息,或等待按鍵:

// 等待指定的時間間隔,并顯示倒計時信息
CLI::wait($seconds, true);

// 顯示等待輸入的信息,并等待輸入
CLI::wait(0, false);

// 等待指定的時間間隔,不顯示任何信息
CLI::wait($seconds, false);