阐述 WordPress `WP_CLI` 类中的 `prompt()` 方法源码:如何请求用户输入。

各位代码界的段子手、键盘上的舞者,大家好!今天咱们来聊聊 WordPress WP_CLI 这个神器里,一个挺好玩儿的方法:prompt()。这玩意儿就像个小喇叭,能直接在命令行里跟你对话,问你问题,然后把你的回答拿去用。 听起来是不是有点意思?好,咱们这就开始 dissect 它,看看它到底是怎么勾搭上用户的。

一、WP_CLI::prompt() 方法概览

首先,咱们得搞清楚 prompt() 这家伙是干啥的。简单来说,它就是在命令行界面(CLI)里,向用户抛出一个问题,然后等待用户输入答案。这个答案呢,会被 prompt() 方法捕捉到,并返回给你,供你后续的代码使用。

想想看,在写一些需要用户交互的 CLI 脚本时,比如创建用户、设置密码、确认操作等等,prompt() 就派上大用场了。它能让你的脚本不再是冷冰冰的一堆指令,而是能跟你“聊天”的智能助手。

二、prompt() 方法源码解读

为了更深入地了解 prompt(),咱们直接扒它的源码(基于 WP-CLI 的某个版本,可能会有细微差异):

/**
 * Prompts the user for input.
 *
 * @param string  $text    Text to display to the user.
 * @param bool    $assoc   Whether to return an associative array.
 * @param mixed   $default Default value to return.
 * @param bool    $regex   Regular expression to validate the input.
 * @return string|array User input.
 */
public static function prompt( $text, $assoc = false, $default = null, $regex = false ) {
    while ( true ) {
        fwrite( STDOUT, $text . ': ' );

        $line = trim( fgets( STDIN ) );

        if ( empty( $line ) && null !== $default ) {
            $line = $default;
        }

        if ( $regex && ! preg_match( $regex, $line ) ) {
            WP_CLI::warning( 'Input does not match the required format.' );
            continue;
        }

        if ( $assoc ) {
            $line = self::parse_csv( $line );
        }

        return $line;
    }
}

咱们一行一行地拆解:

  1. public static function prompt( $text, $assoc = false, $default = null, $regex = false ):

    • 这是一个静态方法,意味着你可以直接通过 WP_CLI::prompt() 调用它,而不需要实例化 WP_CLI 类。
    • $text:这是要显示给用户的提示信息,比如 "请输入用户名"。
    • $assoc:一个布尔值,如果为 true,则将用户输入解析为关联数组(稍后会讲到)。
    • $default:默认值,如果用户直接回车,则返回此值。
    • $regex:正则表达式,用于验证用户的输入是否符合要求。
  2. while ( true ) { ... }:

    • 这是一个无限循环,除非用户输入了有效的值,或者程序出错,否则会一直循环下去。
  3. fwrite( STDOUT, $text . ': ' );:

    • fwrite() 函数用于向标准输出流(STDOUT)写入数据。
    • STDOUT 是一个预定义的常量,代表标准输出流,通常是命令行终端。
    • 这行代码的作用是在命令行中显示 $text,并在后面加上 ": ",提示用户输入。
  4. $line = trim( fgets( STDIN ) );:

    • fgets( STDIN ) 从标准输入流(STDIN)读取一行数据,直到遇到换行符。
    • STDIN 是一个预定义的常量,代表标准输入流,通常是用户的键盘输入。
    • trim() 函数用于去除字符串两端的空白字符。
    • 这行代码的作用是读取用户输入的一行数据,并去除首尾的空白字符,然后将其赋值给变量 $line
  5. if ( empty( $line ) && null !== $default ) { $line = $default; }:

    • empty( $line ) 检查 $line 是否为空字符串。
    • null !== $default 检查 $default 是否被设置了非空值。
    • 如果用户直接回车,$line 将为空字符串,此时如果设置了 $default,则将 $default 的值赋给 $line
  6. if ( $regex && ! preg_match( $regex, $line ) ) { ... }:

    • $regex 检查是否设置了正则表达式。
    • preg_match( $regex, $line ) 使用正则表达式 $regex 匹配 $line
    • 如果设置了正则表达式,并且用户输入的值不符合正则表达式的规则,则显示一个警告信息,并继续循环,要求用户重新输入。
  7. if ( $assoc ) { $line = self::parse_csv( $line ); }:

    • 如果 $assoctrue,则调用 self::parse_csv() 方法将 $line 解析为关联数组。 稍后会详细解释 parse_csv()
  8. return $line;:

    • 返回用户输入的值(经过处理后的)。

三、parse_csv() 方法解析

咱们来看看 parse_csv() 这个小助手,它能把用户输入的逗号分隔的值变成一个关联数组。 源码如下:

/**
 * Parses a CSV line into an associative array.
 *
 * @param string $line Line to parse.
 * @return array
 */
private static function parse_csv( $line ) {
    $data   = str_getcsv( $line );
    $return = array();

    foreach ( $data as $datum ) {
        list( $key, $value ) = array_pad( explode( '=', $datum, 2 ), 2, null );

        if ( null === $value ) {
            $value = $key;
        }

        $return[ $key ] = $value;
    }

    return $return;
}
  1. private static function parse_csv( $line ):

    • 一个私有静态方法,只能在 WP_CLI 类内部调用。
  2. $data = str_getcsv( $line );:

    • str_getcsv() 函数是 PHP 内置的函数,用于将 CSV 字符串解析为数组。 它会根据逗号分隔符将字符串分割成多个字段。
  3. $return = array();:

    • 初始化一个空数组,用于存储解析后的关联数组。
  4. foreach ( $data as $datum ) { ... }:

    • 循环遍历 CSV 数组中的每个字段。
  5. list( $key, $value ) = array_pad( explode( '=', $datum, 2 ), 2, null );:

    • explode( '=', $datum, 2 ) 将每个字段按照 = 分割成键和值。 2 表示最多分割成两部分。
    • array_pad( ..., 2, null ) 确保分割后的数组至少有两个元素(键和值),如果只有一个元素,则用 null 填充第二个元素。
    • list( $key, $value ) 将数组中的元素分别赋值给 $key$value
  6. if ( null === $value ) { $value = $key; }:

    • 如果 $valuenull,表示用户只输入了键,没有输入值,此时将 $key 的值赋给 $value
  7. $return[ $key ] = $value;:

    • 将键值对存储到 $return 数组中。
  8. return $return;:

    • 返回解析后的关联数组。

四、prompt() 的使用姿势

咱们来演示一下 prompt() 的各种用法,让你彻底掌握它。

  1. 简单提示

    $username = WP_CLI::prompt( '请输入用户名' );
    WP_CLI::line( '你输入的用户名是:' . $username );

    这段代码会在命令行中显示 "请输入用户名: ",然后等待用户输入,并将用户输入的值存储到 $username 变量中,最后输出 "你输入的用户名是:[用户输入]"。

  2. 带默认值的提示

    $email = WP_CLI::prompt( '请输入邮箱', false, '[email protected]' );
    WP_CLI::line( '你输入的邮箱是:' . $email );

    这段代码会在命令行中显示 "请输入邮箱: ",如果用户直接回车,则 $email 的值为 "[email protected]"。

  3. 带正则表达式验证的提示

    $phone = WP_CLI::prompt( '请输入手机号(11位数字)', false, null, '/^d{11}$/' );
    WP_CLI::line( '你输入的手机号是:' . $phone );

    这段代码会在命令行中显示 "请输入手机号(11位数字): ",并使用正则表达式 /^d{11}$/ 验证用户输入的值是否为 11 位数字。 如果不符合规则,则会显示警告信息,并要求用户重新输入。

  4. 解析为关联数组的提示

    $data = WP_CLI::prompt( '请输入键值对 (key1=value1,key2=value2)', true );
    WP_CLI::line( '你输入的数据是:' );
    WP_CLI::print_r( $data );

    这段代码会在命令行中显示 "请输入键值对 (key1=value1,key2=value2): ",如果用户输入 "name=John,age=30",则 $data 的值为:

    array(
        'name' => 'John',
        'age'  => '30',
    )

    如果用户输入 "name=John,age",则 $data 的值为:

    array(
        'name' => 'John',
        'age'  => 'age',
    )

    如果用户输入 "name,age",则 $data 的值为:

    array(
        'name' => 'name',
        'age'  => 'age',
    )

五、表格总结

为了方便大家理解,咱们用表格来总结一下 prompt() 方法的参数:

参数 类型 描述
$text string 要显示给用户的提示信息。
$assoc boolean 是否将用户输入解析为关联数组。
$default mixed 默认值,如果用户直接回车,则返回此值。
$regex string 正则表达式,用于验证用户的输入是否符合要求。

六、使用场景举例

  1. 创建用户: 你可以用 prompt() 询问用户的用户名、密码、邮箱等信息,然后创建一个新的 WordPress 用户。

  2. 更新配置: 你的 CLI 工具可以询问用户要修改哪些配置项,以及新的值,然后更新配置文件。

  3. 数据库操作: 你可以询问用户要执行的 SQL 语句,然后在数据库中执行。 (注意安全,要对用户输入进行过滤和转义!)

  4. 文件操作: 你可以询问用户要创建、修改或删除的文件名,然后执行相应的文件操作。

七、注意事项

  • 安全性: 如果你使用 prompt() 获取用户输入,并将其用于数据库操作或文件操作,一定要注意安全性,对用户输入进行过滤和转义,防止 SQL 注入或命令注入攻击。

  • 用户体验: 尽量提供清晰的提示信息,让用户知道需要输入什么样的数据。 如果需要,可以使用正则表达式验证用户输入,并给出友好的错误提示。

  • 错误处理: 考虑各种可能的错误情况,例如用户输入了无效的数据,或者发生了其他异常,并进行适当的处理。

八、总结

WP_CLI::prompt() 方法是 WP-CLI 中一个非常实用的工具,它可以让你在命令行脚本中与用户进行交互,获取用户输入,并根据用户输入执行不同的操作。 掌握 prompt() 方法,可以让你的 CLI 工具更加灵活、强大,也更加人性化。

希望今天的讲解能帮助你更好地理解 WP_CLI::prompt() 方法,并在实际项目中灵活运用。 记住,代码的世界是充满乐趣的,只要你敢于探索,勇于尝试,就能创造出无限的可能。

好了,今天的讲座就到这里,祝大家编码愉快,bug 永不相见! 如果有什么问题,欢迎随时提问,咱们下次再见!

发表回复

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