CLI Library?
CodeIgniter 的 CLI 庫,讓創(chuàng)建命令行交互腳本變得簡單。其中包括:
- 為用戶提供更多信息
- 在終端上打印彩色文本
- Beeping (be nice!)
- 在長任務(wù)中顯示進(jìn)度條
- 讓長文本行適應(yīng)窗口
初始化類?
你不需要?jiǎng)?chuàng)建 CLI 庫的實(shí)例,因?yàn)樗乃蟹椒ǘ际庆o態(tài)方法。你只需要確保你的控制器可以通過 use
聲明找到它:
<?php namespace App\Controllers;
use CodeIgniter\CLI\CLI;
class MyController extends \CodeIgniter\Controller
{
. . .
}
首次加載該文件時(shí),這個(gè)類會(huì)自動(dòng)初始化。
獲取用戶輸入?
有時(shí)你需要詢問用戶更多的信息。他們可能沒有提供可選的命令行參數(shù),或者腳本遇到了存在的文件,在覆寫前需要進(jìn)行確認(rèn)。
這時(shí)使用 prompt()
方法處理
你可以提供一個(gè)問題作為方法的第一個(gè)參數(shù):
$color = CLI::prompt('What is your favorite color?');
你可以提供一個(gè)默認(rèn)的答案作為方法的第二個(gè)參數(shù)。如果用戶沒有任何輸入,只是按下 Enter 鍵,則將使用該默認(rèn)答案:
$color = CLI::prompt('What is your favorite color?', 'blue');
你可以向第二個(gè)參數(shù)傳入允許答案的數(shù)組,以限制可以接受的答案:
$overwrite = CLI::prompt('File exists. Overwrite?', ['y','n']);
最后你可以將驗(yàn)證規(guī)則作為第三個(gè)參數(shù),以限制輸入的答案:
$email = CLI::prompt('What is your email?', null, 'required|valid_email');
提供反饋?
write()
多個(gè)方法可以用來向用戶提供反饋。它可以像更新單個(gè)狀態(tài)一樣簡單,也可以包裝復(fù)雜的信息表到用戶終端。
其核心是 write()
方法,該方法將要輸出的字符串作為第一個(gè)參數(shù):
CLI::write('The rain in Spain falls mainly on the plains.');
你可以輸入顏色名稱作為第二個(gè)參數(shù)來更改文本的顏色:
CLI::write('File created.', 'green');
你可以向第三個(gè)參數(shù)輸入顏色名稱來設(shè)置背景顏色。這可以用于按狀態(tài)區(qū)分消息,或使用其他顏色創(chuàng)建“標(biāo)題”:
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
少數(shù)可以用作背景色:
- black
- blue
- green
- cyan
- red
- yellow
- light_gray
- magenta
print()
Print 方法的功能和 write
相同,不同的是它不會(huì)在行前或者行尾強(qiáng)制換行。它將信息打印到當(dāng)前屏幕光標(biāo)所在的位置上,
這讓你可以在不同的代碼位置,打印信息到屏幕的同一行上。當(dāng)你顯示狀態(tài),執(zhí)行某些操作后在同一行打印 “Done” 時(shí),這十分有用:
for ($i = 0; $i <= 10; $i++)
{
CLI::print($i);
}
color()
write()
方法將單行文本打印到終端,并打印 EOL 標(biāo)識(shí)符結(jié)尾。color()
方法以相同的方式處理文本,不同的是它不會(huì)在結(jié)尾打印 EOL 標(biāo)識(shí)符。
這可以讓你在同一行創(chuàng)建多個(gè)輸出。更常見的用法是在 write()
方法內(nèi)部使用,以在同一行中顯示不同顏色的文本:
CLI::write("fileA \t". CLI::color('/path/to/file', 'white'), 'yellow');
該示例將打印一行文本到終端。首先用黃色打印 fileA
,接著打印一個(gè)制表符,最后用白色打印 /path/to/file
。
error()
如果你需要輸出錯(cuò)誤信息,則應(yīng)該使用 error
方法。它會(huì)將淺紅色的文本寫入到 STDERR
,而不是像 write()
和 color()
一樣寫入到 STDOUT
。
如果你使用腳本監(jiān)視錯(cuò)誤信息,這樣就可以只捕獲到實(shí)際的錯(cuò)誤信息,不必從所有信息中進(jìn)行篩選:
CLI::error('Cannot write to file: ' . $file);
wrap()
該方法將獲取一個(gè)字符串,并開始在當(dāng)前行開始打印。它將會(huì)根據(jù)設(shè)置的長度對(duì)字符串進(jìn)行包裝,每行只顯示設(shè)置的長度的內(nèi)容。 他可以用來顯示帶有說明的顯示列表,避免過多內(nèi)容顯示在一行內(nèi),影響閱讀:
CLI::color("task1\t", 'yellow');
CLI::wrap("Some long description goes here that might be longer than the current window.");
默認(rèn)情況下,字符串將用終端寬度進(jìn)行包裝。Windows 目前無法提供確定的窗口大小,所以默認(rèn)使用 80 個(gè)字符。如果你希望將寬度設(shè)置的更短一些, 可以將最大行長度作為第二個(gè)參數(shù)傳遞。這將在最接近該長度的單詞處斷開字符,以避免破壞單詞:
// Wrap the text at max 20 characters wide
CLI::wrap($description, 20);
你會(huì)發(fā)現(xiàn)需要左邊需要一列顯示標(biāo)題、文件或任務(wù),而右邊需要一列顯示文本和他的說明。默認(rèn)情況下, 這將換行到窗口的左邊緣,即不允許信息按列排列。這時(shí)你可以用空格來填充第一行之后的每一行, 以便讓左側(cè)具有清晰的列邊緣:
// 確定所有標(biāo)題的最大長度
// 確定左列的寬度
$maxlen = max(array_map('strlen', $titles));
for ($i=0; $i < count($titles); $i++)
{
CLI::write(
// 在行的左側(cè)列顯示標(biāo)題
$titles[$i] . ' ' .
// 在行的右側(cè)列包裝信息
// 與左側(cè)最寬的內(nèi)容間隔三個(gè)寬度
CLI::wrap($descriptions[$i], 40, $maxlen + 3)
);
}
將創(chuàng)建以下內(nèi)容:
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()
方法向用戶顯示一個(gè)空行,它不需要任何參數(shù):
CLI::newLine();
clearScreen()
你可以使用 clearScreen()
方法清除當(dāng)前窗口。在多數(shù)的 Windows 系統(tǒng)中,它將插入 40 行空白行,因?yàn)?Windows 不支持該功能。
Windows 10 bash 因該能改變這點(diǎn):
CLI::clearScreen();
showProgress()
如果你有一個(gè)長時(shí)間運(yùn)行的任務(wù),你希望讓用戶了解當(dāng)前的執(zhí)行進(jìn)度,則可以使用 showProgress()
方法,它顯示以下內(nèi)容:
[####......] 40% Complete
該行將設(shè)置為動(dòng)態(tài)顯示,以獲得良好的展示效果。
將當(dāng)前的步驟作為第一個(gè)參數(shù)傳入,并將總步驟作為第二個(gè)參數(shù)傳入。完成的百分比和顯示長度將根據(jù)該數(shù)字確認(rèn)。當(dāng)任務(wù)完成后,傳遞 false 作為第一個(gè)參數(shù),進(jìn)度條將被刪除:
$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()
等待一定的秒數(shù)??梢赃x擇顯示等待消息,或等待按鍵:
// 等待指定的時(shí)間間隔,并顯示倒計(jì)時(shí)信息
CLI::wait($seconds, true);
// 顯示等待輸入的信息,并等待輸入
CLI::wait(0, false);
// 等待指定的時(shí)間間隔,不顯示任何信息
CLI::wait($seconds, false);