大家有没有注意到,在我们使用 composer
进行依赖管理的时候,它在命令行中的输出竟然是彩色的,而我们自己写的程序使用 echo
进行输出的时候,都是默认的黑底白字(依赖于主题),逼格一点都不高!
探究开始
为了探究命令行带颜色输出,我查看了安装 composer
时从官方下载的 composer-setup.php
,其中的字符输出函数如下:
/**
* colorize output
*/
function out($text, $color = null, $newLine = true)
{
$styles = array(
'success' => "\033[0;32m%s\033[0m",
'error' => "\033[31;31m%s\033[0m",
'info' => "\033[33;33m%s\033[0m"
);
$format = '%s';
if (isset($styles[$color]) && USE_ANSI) {
$format = $styles[$color];
}
if ($newLine) {
$format .= PHP_EOL;
}
printf($format, $text);
}
可以看到,这个函数中定义了三种类型的色彩输出,而且都是用形如 \033[Xm
的特殊字符串将其包装之后进行的输出,所以,这个形式的特殊字符串究竟是个什么神奇东西?
ANSI转义序列
经过查询资料,发现上一节中所述的神奇字符串是 ANSI
转义序列[1] ,通过它可以控制文字在终端上的样式,如加粗、斜体、颜色等。ANSI
转义序列的解析在终端进行,不同的终端的对其的支持程度也不尽相同,本文采用的终端是 xShell
,已经可以支持大部分的转移序列。
序列写法
ANSI
转义序列以 ESC
转义字符(ASCII码为27) 和 字符[
开始,以字符 m
结束,上一节代码中的 ESC转移字符串 采用了八进制的写法,在实际使用中我们也可以用 \e 这样的转义写法。
牛刀小试
在终端执行如下命令:
echo -e "\e[38;5;1m红色\e[0m"
可以看到终端中将出现如下输出:
文字变成红色的了!
那么上述指令时怎么控制文字的颜色的呢?
紧跟在 [ 之后数字 38 告诉终端转义序列要控制文字的前景色了,后续的 5 表示采用 256色,1 表示使用红色,随即转义序列以 m 结束,进入一般字符串部分;
在字符串的最后,又开始了一个转义序列,数字 0 表示重置所有的字体样式处理,以防止本条指令执行之后还会影响其他指令的颜色输出;
控制参数
来点骚操作
ANSI转义序列对于文字样式的控制效果时可以叠加的,使用示例如下:
echo -e "\e[38;5;255;48;5;1;1;4;9;5m红底白字加粗闪烁\e[0m\e[38;5;4;1m蓝色加粗\e[0m"
输出如下:
注意:上述样例中蓝色加粗部分在定义样式之前使用字符串\e[0m 清除了之前所配置的样式,如果不执行这一步,蓝色加粗部分字体还会携带红色背景和闪烁效果。
在PHP中运用
可以观察到上我们在上一节中我们所使用的 echo 指令都带上了 -e 参数来进行特殊字符处理,那么PHP中要怎么使用ANSI转义序列呢?
经过本人的亲测,PHP中的语法接口 echo 是会进行特殊字符处理的,所以上述样例在PHP代码中可以这么写:
<?php
echo "\e[38;5;255;48;5;1;1;4;9;5m红底白字加粗闪烁\e[0m\e[38;5;4;1m蓝色加粗\e[0m", PHP_EOL;
脚本的运行结果同上面截图中的一致。
工具化
每次调整文字的样式都要写那么一串转义序列太麻烦了,而且可读性也很差。
为了更方便地在PHP程序中输出样式丰富的字符串到终端,我们需要实现一个工具类。