bramus / ansi-php
PHP CLI 应用程序的 ANSI 控制函数和 ANSI 控制序列(颜色、清除等)
Requires
- php: >=5.4.0
Requires (Dev)
- phpunit/phpunit: ~4.0
README
PHP CLI 应用的 ANSI 控制函数和 ANSI 控制序列
由 Bramus 构建! - https://www.bram.us/
关于
bramus/ansi-php
是一套用于在基于文本的终端上操作 ANSI 控制函数和 ANSI 控制序列的类。
- ANSI 控制函数控制诸如行间距、分页或数据流等动作。
- ANSI 控制序列允许清除屏幕、移动光标、设置文本颜色等。
(备注:一个“ANSI 转义序列”是“ANSI 控制序列”的一种特殊类型,它以 ESC ANSI 控制函数开始。这两个术语不可互换。)
特性
当涉及到 ANSI 控制函数时,bramus/ansi-php
支持
BS
: 退格BEL
: 欢叫CR
: 回车ESC
: 转义LF
: 换行TAB
: 制表符
当涉及到 ANSI 转义序列时,bramus/ansi-php
支持
- CUB (光标回移): 移动光标回移。
- CUD (光标下移): 移动光标下移。
- CUF (光标前移): 移动光标前移。
- CUP (光标定位): 将光标移动到指定位置。
- CUU (光标上移): 移动光标上移。
- ED (清除显示): 清除(部分)显示。
- EL (清除行): 清除(部分)当前行。
- SGR (选择图形表示): 操作文本样式(粗体、下划线、闪烁、颜色等)。
其他控制序列(如 DCH、NEL 等)尚不支持。
使用 bramus/ansi-php
的示例库是 bramus/monolog-colored-line-formatter
。它使用 bramus/ansi-php
的 SGR 支持来着色输出
先决条件/要求
- PHP 5.4.0 或更高版本
安装
可以使用 Composer 进行安装
composer require bramus/ansi-php ~3.1
使用方法
使用 ANSI PHP 最简单的方法是使用捆绑的 Ansi
辅助类,该类提供与 bramus/ansi-php
一起工作的简单快捷方式。该 Ansi
类编写得可以这样,即可以链式调用。
如果您喜欢冒险,当然可以自由地使用原始的 ControlFunction
和 ControlSequence
类。
快速示例
use \Bramus\Ansi\Ansi; use \Bramus\Ansi\Writers\StreamWriter; use \Bramus\Ansi\ControlSequences\EscapeSequences\Enums\SGR; // Create Ansi Instance $ansi = new Ansi(new StreamWriter('php://stdout')); // Output some styled text on screen, along with a Line Feed and a Bell $ansi->color(array(SGR::COLOR_FG_RED, SGR::COLOR_BG_WHITE)) ->blink() ->text('I will be blinking red on a white background.') ->nostyle() ->text(' And I will be normally styled.') ->lf() ->text('Ooh, a bell is coming ...') ->bell();
以下将提供更多示例说明如何使用这些类。
概念
从 v3.0 开始,bramus/ansi-php
使用了写入器的概念来写入数据。默认情况下,使用一个写入到 php://stdout
的 StreamWriter
。
以下提供以下写入器
StreamWriter
: 将数据写入流。只需传递文件路径,它将为您打开一个流。默认写入到php://stdout
。BufferWriter
: 将数据写入缓冲区。在调用flush()
时,将返回缓冲区的内容。ProxyWriter
: 作为其他写入器的代理。将数据写入内部缓冲区。在调用flush()
时,写入器将首先将数据写入其他写入器,然后返回。
Ansi
辅助类的功能
核心函数
text($text)
: 将数据写入写入器setWriter(\Bramus\Ansi\Writers\WriterInterface $writer)
: 设置写入器getWriter()
: 获取写入器
ANSI 控制函数快捷方式
这些缩写将控制字符写入写入器。
bell()
:铃铛控制字符(《\a》)backspace()
:退格控制字符(《\b》)tab()
:制表符控制字符(《\t》)lf()
:换行控制字符(《\n》)cr()
:回车控制字符(《\r》)esc()
:转义控制字符
SGR ANSI 转义序列缩写
这些缩写将 SGR ANSI 转义序列写入写入器。
nostyle()
或reset()
:移除所有文本样式(颜色、粗体等)color()
:设置文本的前景色和/或背景色。(见下文)bold()
或bright()
:粗体:开启。在某些系统中“强度:明亮”normal()
:粗体:关闭。在某些系统中“强度:正常”faint()
:强度:淡。 (支持度不高)italic()
:斜体:开启。 (支持度不高)underline()
:下划线:开启。blink()
:闪烁:开启。negative()
:反色或反转。交换前景和背景。strikethrough()
:删除线:开启。 (支持度不高)
重要:选择图形表示方式(Select Graphic Rendition)的工作方式是,您设置的文本样式将保持活动状态,直到您调用 nostyle()
或 reset()
以返回默认样式。
ED ANSI 转义序列缩写
这些缩写将 ED ANSI 转义序列写入写入器。
eraseDisplay()
:清除整个屏幕并将光标移到起始位置。eraseDisplayUp()
:清除从当前行向上到屏幕顶部的屏幕。eraseDisplayDown()
:清除从当前行向下到屏幕底部的屏幕。
EL ANSI 转义序列缩写
这些缩写将 EL ANSI 转义序列写入写入器。
eraseLine()
:清除整个当前行。eraseLineToEOL()
:从当前光标位置清除到当前行的末尾。eraseLineToSOL()
:从当前光标位置清除到当前行的开头。
CUB/CUD/CUF/CUP/CUU ANSI 转义序列缩写
cursorBack($n)
:将光标向后移动$n
个位置 (默认:1)cursorForward($n)
:将光标向前移动$n
个位置 (默认:1)cursorDown($n)
:将光标向下移动$n
个位置 (默认:1)cursorUp($n)
:将光标向上移动$n
个位置 (默认:1)cursorPosition($n, $m)
:将光标移动到位置$n,$m
(默认:1,1)
额外功能
flush()
或get()
:检索FlushableWriter
写入器的内容。e()
:回显FlushableWriter
写入器的内容。
示例
基础
// Create Ansi Instance $ansi = new \Bramus\Ansi\Ansi(); // This will output a Bell $ansi->bell(); // This will output some text $ansi->text('Hello World!');
注意:由于没有将 $writer
传递给 \Bramus\Ansi\Ansi
的构造函数,因此使用默认的 StreamWriter
写入到 php://stdout
。
使用 FlushableWriter
可刷新的写入器是缓存数据的写入器,只有在使用其 flush()
函数刷新时才会输出数据。《BufferWriter》 和 《ProxyWriter》 实现了此接口。
// Create Ansi Instance $ansi = new \Bramus\Ansi\Ansi(new \Bramus\Ansi\Writers\BufferWriter()); // This will append a bell to the buffer. It will not output it. $ansi->bell(); // This will append a bell to the buffer. It will not output it. $ansi->text('Hello World!'); // Now we'll output it echo $ansi->get();
链式调用
《bramus/ansi-php》 的包装类 《Ansi》 支持链式调用。
// Create Ansi Instance $ansi = new \Bramus\Ansi\Ansi(); // This will output a Line Feed, some text, a Bell, and a Line Feed $ansi->lf()->text('hello')->bell()->lf();
文本样式:基础
$ansi = new \Bramus\Ansi\Ansi(); $ansi->bold()->underline()->text('I will be bold and underlined')->lf();
重要:选择图形表示方式(Select Graphic Rendition)的工作方式是,您设置的文本样式将保持活动状态,直到您调用 nostyle()
或 reset()
以返回默认样式。
$ansi = new \Bramus\Ansi\Ansi(); $ansi->bold()->underline()->text('I will be bold and underlined')->lf(); $ansi->text('I will also be bold because nostyle() has not been called yet')->lf(); $ansi->nostyle()->blink()->text('I will be blinking')->nostyle()->lf(); $ansi->text('I will be normal because nostyle() was called on the previous line');
文本样式:颜色
颜色和其他文本样式选项是在 \Bramus\Ansi\ControlSequences\EscapeSequences\Enums\SGR
上定义的常量。
前景(文本)颜色
SGR::COLOR_FG_BLACK
:黑色前景颜色SGR::COLOR_FG_RED
:红色前景颜色SGR::COLOR_FG_GREEN
:绿色前景颜色SGR::COLOR_FG_YELLOW
:黄色前景颜色SGR::COLOR_FG_BLUE
:蓝色前景颜色SGR::COLOR_FG_PURPLE
:紫色前景颜色SGR::COLOR_FG_CYAN
:青色前景颜色SGR::COLOR_FG_WHITE
:白色前景颜色SGR::COLOR_FG_BLACK_BRIGHT
:黑色前景颜色(亮色)SGR::COLOR_FG_RED_BRIGHT
:红色前景颜色(亮色)SGR::COLOR_FG_GREEN_BRIGHT
:绿色前景颜色(亮色)SGR::COLOR_FG_YELLOW_BRIGHT
:黄色前景颜色(亮色)SGR::COLOR_FG_BLUE_BRIGHT
:蓝色前景颜色(亮色)SGR::COLOR_FG_PURPLE_BRIGHT
:紫色前景颜色(亮色)SGR::COLOR_FG_CYAN_BRIGHT
:青色前景颜色(亮色)SGR::COLOR_FG_WHITE_BRIGHT
:白色前景颜色(亮色)SGR::COLOR_FG_RESET
:默认前景颜色
背景颜色
SGR::COLOR_BG_BLACK
:黑色背景颜色SGR::COLOR_BG_RED
:红色背景颜色SGR::COLOR_BG_GREEN
:绿色背景颜色SGR::COLOR_BG_YELLOW
:黄色背景颜色SGR::COLOR_BG_BLUE
:蓝色背景颜色SGR::COLOR_BG_PURPLE
:紫色背景颜色SGR::COLOR_BG_CYAN
:青色背景颜色SGR::COLOR_BG_WHITE
:白色背景颜色SGR::COLOR_BG_BLACK_BRIGHT
:黑色背景颜色(亮色)SGR::COLOR_BG_RED_BRIGHT
:红色背景颜色(亮色)SGR::COLOR_BG_GREEN_BRIGHT
:绿色背景颜色(亮色)SGR::COLOR_BG_YELLOW_BRIGHT
:黄色背景颜色(亮色)SGR::COLOR_BG_BLUE_BRIGHT
:蓝色背景颜色(亮色)SGR::COLOR_BG_PURPLE_BRIGHT
:紫色背景颜色(亮色)SGR::COLOR_BG_CYAN_BRIGHT
:青色背景颜色(亮色)SGR::COLOR_BG_WHITE_BRIGHT
:白色背景颜色(亮色)SGR::COLOR_BG_RESET
:默认背景颜色
将其中之一传递给$ansi->color()
,颜色将被设置。
use \Bramus\Ansi\ControlSequences\EscapeSequences\Enums\SGR; $ansi = new \Bramus\Ansi\Ansi(); $ansi->color(SGR::COLOR_FG_RED) ->text('I will be red') ->nostyle();
要在一 个调用中设置前景和背景颜色,请使用数组通过$ansi->color()
传递它们
use \Bramus\Ansi\ControlSequences\EscapeSequences\Enums\SGR; $ansi = new \Bramus\Ansi\Ansi(); $ansi->color(array(SGR::COLOR_FG_RED, SGR::COLOR_BG_WHITE)) ->blink() ->text('I will be blinking red on a wrhite background.') ->nostyle();
创建一个加载指示器
通过操作光标位置,可以创建一个内联指示器
use \Bramus\Ansi\Ansi; use \Bramus\Ansi\Writers\StreamWriter; use \Bramus\Ansi\ControlSequences\EscapeSequences\Enums\EL; use \Bramus\Ansi\ControlSequences\EscapeSequences\Enums\SGR; // Create Ansi Instance $ansi = new Ansi(new StreamWriter('php://stdout')); // Parts of our spinner $spinnerParts = ['⣷','⣯','⣟','⡿','⢿','⣻','⣽','⣾']; $ansi->text('Loading Data')->lf(); for ($i = 0; $i < 100; $i++) { $ansi // Erase entire line ->el(EL::ALL) // Go back to very first position on current line ->cursorBack(9999) // Add a blue spinner ->color(SGR::COLOR_FG_BLUE)->text($spinnerParts[$i % sizeof($spinnerParts)]) // Write percentage ->nostyle()->text(' ' . str_pad($i, 3, 0, STR_PAD_LEFT) . '%'); usleep(50000); } $ansi ->el(EL::ALL) ->cursorBack(9999) ->color(SGR::COLOR_FG_GREEN)->text('✔') ->nostyle()->text(' 100%') ->lf();
此代码片段将输出一个小型加载指示器图标 + 当前百分比(例如⣯ 009%
),它不断更新。当达到100%时,行将显示为✔ 100%
。
使用原始类
由于所有原始ControlFunction
和ControlSequence
类都提供了__toString()
函数,因此可以直接echo
某些bramus/ansi-php
实例。
// Output a Bell Control Character echo new \Bramus\Ansi\ControlFunctions\Bell(); // Output an ED instruction, to erase the entire screen echo new \Bramus\Ansi\ControlSequences\EscapeSequences\ED( \Bramus\Ansi\ControlSequences\EscapeSequences\Enums\ED::ALL );
要获取其内容,请使用get()
函数
// Get ANSI string for a Bell Control Character $bell = (new \Bramus\Ansi\ControlFunctions\Bell())->get(); // Get ANSI string for an ED instruction, to erase the entire screen $eraseDisplay = (new \Bramus\Ansi\ControlSequences\EscapeSequences\ED( \Bramus\Ansi\ControlSequences\EscapeSequences\Enums\ED::ALL ))->get(); echo $bell . $bell . $eraseDisplay . $bell;
单元测试
bramus/ansi-php
附带单元测试,使用PHPUnit。
-
如果PHPUnit已全局安装,请运行
phpunit
以运行测试。 -
如果没有全局安装PHPUnit,请通过运行
composer install --dev
在本地安装它。通过调用vendor/bin/phpunit
或composer test
来运行测试本身。
单元测试还自动在Travis CI上运行
许可协议
bramus/ansi-php
在MIT公共许可协议下发布。有关详细信息,请参阅附带的LICENSE
文件。
ANSI参考
- http://en.wikipedia.org/wiki/ANSI_escape_code
- http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-048.pdf
- http://wiki.bash-hackers.org/scripting/terminalcodes
- http://web.mit.edu/gnu/doc/html/screen_10.html
- http://www.isthe.com/chongo/tech/comp/ansi_escapes.html
- http://www.termsys.demon.co.uk/vtansi.htm
- http://rrbrandt.dee.ufcg.edu.br/en/docs/ansi/
- https://tldp.cn/HOWTO/Bash-Prompt-HOWTO/c327.html