解析 WordPress `WP_CLI` 类中的 `success()`、`error()`、`log()` 方法源码:如何处理命令行的输出。

WordPress 命令行魔法:WP_CLI 输出处理大揭秘 (Success, Error, Log)

各位代码爱好者们,晚上好!我是你们的老朋友,今天咱们来聊聊 WordPress 命令行工具 WP_CLI 中那些负责“说话”的方法:success()error()log()。 别看它们名字简单,背后可藏着不少控制命令行输出的秘密呢!

想象一下,你正用 WP_CLI 执行一个复杂的任务,比如迁移整个网站。如果一切顺利,你肯定希望看到一个绿色的“成功”提示;如果出了问题,一个醒目的红色“错误”警报能帮你快速定位问题。这些,都离不开这三个“输出小能手”。

1. WP_CLI 的“嘴巴”:success(), error(), log()

首先,让我们认识一下这三个方法:

  • WP_CLI::success( string $message, array $data = [] ): 用于输出成功信息。通常会带有一个绿色的勾勾,让你感觉一切都棒棒哒!
  • WP_CLI::error( string $message, array $data = [] ): 用于输出错误信息。通常会带有一个红色的叉叉,告诉你哪里出错了。
  • WP_CLI::log( string $message, array $data = [] ): 用于输出普通信息。就像一个默默的记录者,告诉你程序正在做什么。

这三个方法都接受两个参数:

  • $message: 要输出的文本信息。 这是核心内容,告诉用户发生了什么。
  • $data: 一个可选的关联数组。可以包含一些额外的信息,这些信息可以通过占位符嵌入到 $message 中。

2. 源码剖析:它们是如何工作的?

要理解它们的工作方式,我们需要稍微深入 WP_CLI 的源码。 虽然完整的源码很长,但我们可以提取关键部分进行分析。

2.1 WP_CLI::success()

<?php
class WP_CLI {
    public static function success( $message, $data = array() ) {
        self::line( self::colorize( "%GSuccess: " . self::interpolate( $message, $data ) . "%n" ) );
    }

    public static function error( $message, $data = array() ) {
        self::line( self::colorize( "%RError: " . self::interpolate( $message, $data ) . "%n" ) );
    }

    public static function log( $message, $data = array() ) {
        self::line( self::interpolate( $message, $data ) );
    }

    protected static function line( $line = '' ) {
        fwrite( STDOUT, $line . PHP_EOL );
    }

    protected static function colorize( $string ) {
        if ( ! self::supports_color() ) {
            return $string;
        }

        $codes = array(
            '%y' => '33',  // Yellow
            '%g' => '32',  // Green
            '%b' => '34',  // Blue
            '%r' => '31',  // Red
            '%p' => '35',  // Purple
            '%m' => '36',  // Magenta
            '%e' => '30',  // Black
            '%n' => '0',   // Reset
            '%Y' => '93',  // Yellow
            '%G' => '92',  // Green
            '%B' => '94',  // Blue
            '%R' => '91',  // Red
            '%P' => '95',  // Purple
            '%M' => '96',  // Magenta
            '%E' => '90',  // Black
            '%W' => '97',  // White
        );

        $string = str_replace( array_keys( $codes ), array_values( $codes ), $string );
        $string = preg_replace( '#(?<!\\)\\([nveygbrpm])#', "33[${1}m", $string );

        return "33[" . $string . 'm';
    }

    protected static function interpolate( $message, array $data = array() ) {
        if ( empty( $data ) ) {
            return $message;
        }

        $replace = array();
        foreach ( $data as $key => $val ) {
            if ( is_scalar( $val ) ) {
                $replace['{' . $key . '}'] = $val;
            }
        }

        return strtr( $message, $replace );
    }

    protected static function supports_color() {
        if ( DIRECTORY_SEPARATOR === '\' ) {
            return ( function_exists( 'sapi_windows_vt100_support' ) && sapi_windows_vt100_support( STDOUT ) );
        }

        return function_exists( 'posix_isatty' ) && posix_isatty( STDOUT );
    }
}
?>

让我们一步步拆解:

  1. self::colorize( "%GSuccess: " . self::interpolate( $message, $data ) . "%n" ): 这是核心步骤。它做了两件事:
    • self::interpolate( $message, $data ): 将 $message 中的占位符替换为 $data 中对应的值。 例如,如果 $message"用户 {username} 创建成功"$data['username' => 'john.doe'],那么这个方法会返回 "用户 john.doe 创建成功"
    • self::colorize( ... ): 给字符串添加颜色代码。 "%G" 表示绿色,"%n" 表示重置颜色。 所以,最终的字符串会被包装成绿色的。
  2. self::line( ... ): 将处理后的字符串输出到命令行。 self::line() 本质上就是 fwrite( STDOUT, $line . PHP_EOL ),将字符串写入标准输出,并在末尾添加一个换行符。

2.2 WP_CLI::error()

WP_CLI::error() 的工作方式与 WP_CLI::success() 非常相似,唯一的区别在于它使用了 "%R" 来表示红色,并添加了 "Error: " 前缀。

2.3 WP_CLI::log()

WP_CLI::log() 相对简单。它只执行了占位符替换 (self::interpolate()),然后直接调用 self::line() 输出。 没有颜色,也没有前缀。

2.4 self::interpolate()

这个方法负责将消息中的占位符替换为实际的值。它遍历 $data 数组,将形如 {key} 的占位符替换为 $data['key'] 的值。

2.5 self::colorize()

这个方法负责给字符串添加颜色。它首先检查当前环境是否支持颜色(通过 self::supports_color() 判断)。如果支持,它会将类似 %G 的颜色代码替换为 ANSI 转义序列,这些序列会被终端识别并解释为颜色。 如果环境不支持颜色,则直接返回原始字符串。

2.6 self::supports_color()

这个方法判断当前环境是否支持颜色输出。在 Windows 环境下,它检查是否支持 VT100 终端模拟。在其他环境下,它检查是否是交互式终端。

3. 实际应用:代码示例

理论讲了一堆,不如来点实际的。 让我们看看如何在 WP_CLI 命令中使用这些方法。

<?php
class My_Command {
    /**
     * 创建一个用户
     *
     * ## OPTIONS
     *
     * <username>
     * : 用户名
     *
     * <email>
     * : 邮箱
     *
     * @when before_wp_load
     */
    public function create_user( $args, $assoc_args ) {
        $username = $args[0];
        $email = $args[1];

        if ( username_exists( $username ) ) {
            WP_CLI::error( "用户名 '{username}' 已存在。", [ 'username' => $username ] );
            return;
        }

        if ( ! is_email( $email ) ) {
            WP_CLI::error( "邮箱 '{email}' 格式不正确。", [ 'email' => $email ] );
            return;
        }

        $user_id = wp_create_user( $username, wp_generate_password(), $email );

        if ( is_wp_error( $user_id ) ) {
            WP_CLI::error( "创建用户失败: " . $user_id->get_error_message() );
            return;
        }

        WP_CLI::success( "用户 '{username}' 创建成功,ID 为 {user_id}。", [ 'username' => $username, 'user_id' => $user_id ] );
    }
}
WP_CLI::add_command( 'my-command create-user', 'My_Command::create_user' );
?>

在这个例子中:

  • 如果用户名已存在或邮箱格式不正确,我们会使用 WP_CLI::error() 输出错误信息,并使用占位符显示具体的值。
  • 如果创建用户失败,我们会使用 WP_CLI::error() 输出 WordPress 错误对象中的错误信息。
  • 如果一切顺利,我们会使用 WP_CLI::success() 输出成功信息,并显示用户名和用户 ID。

使用示例:

wp my-command create-user john.doe [email protected]

可能的输出:

  • 成功: Success: 用户 'john.doe' 创建成功,ID 为 123。 (绿色)
  • 用户名已存在: Error: 用户 'john.doe' 已存在。 (红色)
  • 邮箱格式不正确: Error: 邮箱 '[email protected]' 格式不正确。 (红色)

4. 颜色代码表:给你的命令行加点颜色

WP_CLI 使用一些简单的颜色代码来控制输出的颜色。 以下是常用的颜色代码表:

代码 颜色 说明
%y 黄色 浅黄色
%g 绿色 浅绿色
%b 蓝色 浅蓝色
%r 红色 浅红色
%p 紫色 浅紫色
%m 品红 浅品红色
%e 黑色 黑色
%n 重置 重置颜色,恢复默认颜色
%Y 亮黄色 深黄色
%G 亮绿色 深绿色
%B 亮蓝色 深蓝色
%R 亮红色 深红色
%P 亮紫色 深紫色
%M 亮品红 深品红色
%E 亮黑色 深黑色
%W 亮白色 深白色

你可以将这些代码嵌入到你的消息字符串中,来控制输出的颜色。例如:

WP_CLI::log( "%R警告:%n 这是一个危险的操作!" ); // 输出红色的 "警告:",然后恢复默认颜色

5. 进阶技巧:自定义输出

虽然 WP_CLI 已经提供了 success()error()log() 这些方法,但有时你可能需要更高级的输出控制。 WP_CLI 也提供了其他一些方法,例如:

  • WP_CLI::line( string $line ): 直接输出一行文本。 没有颜色,也没有占位符替换。
  • WP_CLI::out( string $string ): 输出一段文本,但不添加换行符。
  • WP_CLI::colorize( string $string ): 给字符串添加颜色代码。
  • WP_CLI::debug( string $message, string $group = 'default' ): 输出调试信息。 只有在开启调试模式时才会显示。
  • WP_CLI::halt( int $exit_code ): 立即停止脚本的执行,并返回指定的退出码。

你还可以使用这些方法组合来实现更复杂的输出逻辑。

6. 总结

WP_CLIsuccess()error()log() 方法是构建用户友好的命令行工具的关键。 通过理解它们的工作方式,以及如何使用颜色代码和占位符,你可以创建更清晰、更易于理解的命令行输出,让你的用户体验更上一层楼。

记住,良好的命令行输出不仅能提供信息,还能帮助用户快速定位问题,并提高工作效率。 花点时间设计你的命令行输出,你会发现这是非常值得的!

好了,今天的分享就到这里。 希望大家有所收获,并在自己的 WP_CLI 命令中灵活运用这些技巧! 下次再见!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注