命令说明书

创建自己的自定义WP-CLI命令可能比看起来更容易 - 您可以使用(repo)动态生成除命令本身之外的所有内容。wp scaffold package

概述

WP-CLI的目标是提供WordPress管理员的完整替代方案;对于您可能希望在WordPress管理中执行的任何操作,应该有一个等效的WP-CLI命令。命令是 WP-CLI 功能的原子单元。 (doc) 就是这样一个命令,就像 (doc) 一样。命令对WordPress用户很有用,因为它们可以提供简单,精确的界面来执行复杂的任务。wp plugin install``wp plugin activate

但是,WordPress管理员是一把无限复杂的瑞士军刀。这个项目不可能只处理每个用例。这就是为什么WP-CLI包含一组常见的内部命令,同时还为第三方编写和注册自己的命令提供了丰富的内部API

WP-CLI命令可以作为独立包分发,也可以与WordPress插件或主题捆绑在一起。对于前者,您可以使用 (repo) 动态生成除命令本身之外的所有内容。wp scaffold package

包之于WP-CLI,就像插件之于WordPress一样。创建WP-CLI包的方法存在明显差异。虽然WP-CLI是/wp-admin不断增长的替代品,但重要的是要注意,在考虑如何使用WordPress API之前,您必须首先编写软件包以使用WP-CLI内部API。

命令类型

捆绑的命令:

  • 通常涵盖标准安装WordPress提供的功能。不过,这条规则也有例外,特别是(doc)。wp search-replace
  • 不要依赖其他组件,例如插件,主题等。
  • 由 WP-CLI 团队维护。

第三方命令:

  • 可以在插件或主题中定义。
  • 可以轻松地将脚手架作为独立项目(存储库)搭建。wp scaffold package
  • 可以独立于包索引中的插件或主题进行分发。

所有命令:

命令剖析

WP-CLI 支持将任何可调用的类、函数或闭包注册为命令。 (doc) 用于内部和第三方命令注册。WP_CLI::add_command()

命令的概要定义命令接受哪些位置参数和关联参数。让我们来看看以下的概要:wp plugin install

$ wp plugin install
usage: wp plugin install <plugin|zip|url>... [--version=<version>] [--force] [--activate] [--activate-network]

在此示例中,是公认的位置参数。事实上,多次接受相同的位置参数(要安装的插件的 slug、ZIP 或 URL)。 是公认的关联论点之一。它用于表示要安装的插件的版本。还要注意参数定义周围的方括号;方括号表示参数是可选的。<plugin|zip|url>...``wp plugin install``[--version=<version>]

WP-CLI还具有一系列适用于所有命令的全局参数。例如,包含意味着您的命令执行将显示所有PHP错误,并为WP-CLI引导过程增加额外的冗长程度。--debug

必需的注册参数

注册命令时,需要两个参数:WP_CLI::add_command()

  1. $name是 WP-CLI 命名空间中的命令名称(例如 或 )。plugin install``post list
  2. $callable是命令的实现,作为可调用的类、函数或闭包。

在以下示例中,每个实例在功能上都是等效的:wp foo

// 1. Command is a function
function foo_command( $args ) {
    WP_CLI::success( $args[0] );
}
WP_CLI::add_command( 'foo', 'foo_command' );

// 2. Command is a closure
$foo_command = function( $args ) {
    WP_CLI::success( $args[0] );
}
WP_CLI::add_command( 'foo', $foo_command );

// 3. Command is a method on a class
class Foo_Command {
    public function __invoke( $args ) {
        WP_CLI::success( $args[0] );
    }
}
WP_CLI::add_command( 'foo', 'Foo_Command' );

// 4. Command is a method on a class with constructor arguments
class Foo_Command {
    protected $bar;
    public function __construct( $bar ) {
        $this->bar = $bar;
    }
    public function __invoke( $args ) {
        WP_CLI::success( $this->bar . ':' . $args[0] );
    }
}
$instance = new Foo_Command( 'Some text' );
WP_CLI::add_command( 'foo', $instance );

重要的是,类的行为与函数和闭包略有不同,因为:

  • 类上的任何公共方法都注册为命令的子命令。例如,给定上面的示例,类上的方法将被注册为 .但。。。bar()``Foo``wp foo bar
  • __invoke()被视为一种神奇的方法。如果一个类实现,命令名称将被注册到该方法,并且该类的其他方法不会被注册为命令。__invoke()

_注意:_从历史上看,WP-CLI 提供了一个要扩展的基类,但是扩展此类不是必需的,也不会更改命令的行为方式。WP_CLI_Command

所有命令都可以注册到它们自己的顶级命名空间(例如 ),也可以作为子命令注册到现有命名空间(例如 )。对于后者,只需将现有命名空间作为命令定义的一部分包含在内。wp foo``wp core foo

class Foo_Command {
    public function __invoke( $args ) {
        WP_CLI::success( $args[0] );
    }
}
WP_CLI::add_command( 'core foo', 'Foo_Command' );

快速而肮脏的执行

为一次性任务编写简短脚本,不需要正式注册 ? 是您的票证(文档)。WP_CLI::add_command() wp eval-file

给定一个文件:simple-command.php

WP_CLI::success( "The script has run!" );

如果该命令不依赖于WordPress,或者WordPress不可用,则可以使用该标志来避免加载WordPress。wp eval-file simple-command.php --skip-wordpress

可选注册参数

WP-CLI 支持两种为命令注册可选参数的方法:通过可调用对象的 PHPDoc,或作为第三个参数传递给 。$args``WP_CLI::add_command()

使用 PHPDoc 进行注释

典型的WP-CLI类如下所示:

/**
 * Implements example command.
 */
class Example_Command {
    function hello( $args, $assoc_args ) {
        list( $name ) = $args;

        // Print the message with type
        $type = $assoc_args['type'];
        WP_CLI::$type( "Hello, $name!" );
    }
}

WP_CLI::add_command( 'example', 'Example_Command' );

此命令的 PHPDoc 以三种方式解释:

短描述

缩写是 PHPDoc 中的第一行:

longdesc

longdesc 是 PHPDoc 的中间部分:

longdesc 中定义的选项被解释为命令的概要

  • <name>是必需的位置参数。将其更改为意味着命令可以接受一个或多个位置参数。将其更改为意味着位置参数是可选的,最后,将其更改为意味着该命令可以接受多个可选的位置参数。<name>...``[<name>]``[<name>...]
  • [--type=<type>]是一个可选的关联参数,默认为“成功”并接受“成功”或“错误”。将其更改为 会将参数更改为充当可选的布尔标志。[--error]
  • [--field[=<value>]]允许将可选参数与值或不带值一起使用。这方面的一个例子是使用全局参数,该参数可以跳过加载所有插件,也可以跳过逗号分隔的插件列表。--skip-plugins[=<plugins>]

命令的概要用于在将参数传递给实现之前验证参数。

调用命令时也会显示 longdesc,例如 。它的语法是Markdown Extra,这里有一些关于WP-CLI如何处理它的更多说明:help``wp help example hello

  • 长篇通常被视为自由格式的文本。和 节名称不是强制执行的,只是通用和推荐。OPTIONS``EXAMPLES
  • 节名称 () 以零缩进着色和打印。## NAME
  • 其他所有内容都缩进 2 个字符,选项说明进一步缩进另外 2 个字符。
  • 自动换行有点棘手。如果要在每行上利用尽可能多的空间,并且不会在下一行获得像一两个单词这样的自动换行工件,请遵循以下规则:
    • 冒号和空格后 75 个字符处的硬换行选项说明。
    • 将其他所有内容硬包装在 90 个字符处。

有关如何格式化命令文档的更多详细信息,请参阅 WP-CLI 的文档标准

文档块标签

这是最后一部分,它紧跟在 longdesc 之后开始:

 ```
  • @when after_wp_load */

以下是已定义标记的列表:

**@subcommand**

在某些情况下,不能使方法名称具有子命令的名称。例如,不能有一个名为 的方法,因为 是 PHP 中的保留关键字。`list``list`

这时标签会派上用场:`@subcommand`

    ```
/**
     * @subcommand list
     */
    function _list( $args, $assoc_args ) {
        ...
    }

    /**
     * @subcommand do-chores
     */
    function do_chores( $args, $assoc_args ) {
        ...
    }

@alias

使用该标记,您可以添加另一种调用子命令的方式。例:@alias

```

/** * @alias hi */ function hello( $args, $assoc_args ) { ... }


$ wp example hi Joe Success: Hello, Joe!


**@when**

这是一个特殊的标签,告诉WP-CLI何时执行命令。它支持[所有已注册的WP-CLI钩子](https://make.wordpress.org/cli/handbook/internal-api/wp-cli-add-hook/)。

大多数WP-CLI命令在WordPress加载后执行。命令的默认行为为:

@when after_wp_load


要在WordPress加载之前运行WP-CLI命令,请使用:

@when before_wp_load


请记住,大多数WP-CLI钩子在加载WordPress之前触发。如果您的命令是从插件或主题加载的,则基本上将被忽略。`@when`

如果使用它的命令是从插件或主题加载的,则它不起作用,因为到那时WordPress本身已经加载了。

#### [WP\_CLI::add\_command() 的第三个$args参数](#wp_cliadd_commands-third-args-parameter)

PHPDoc 支持的每个配置选项都可以作为命令注册中的第三个参数传递:

$hello_command = function( $args, $assoc_args ) { list( $name ) = $args; $type = $assoc_args['type']; WP_CLI::$type( "Hello, $name!" ); if ( isset( $assoc_args['honk'] ) ) { WP_CLI::log( 'Honk!' ); } }; WP_CLI::add_command( 'example hello', $hello_command, array( 'shortdesc' => 'Prints a greeting.', 'synopsis' => array( array( 'type' => 'positional', 'name' => 'name', 'description' => 'The name of the person to greet.', 'optional' => false, 'repeating' => false, ), array( 'type' => 'assoc', 'name' => 'type', 'description' => 'Whether or not to greet the person with success or error.', 'optional' => true, 'default' => 'success', 'options' => array( 'success', 'error' ), ), array( 'type' => 'flag', 'name' => 'honk', 'optional' => true, ), ), 'when' => 'after_wp_load', 'longdesc' => '## EXAMPLES' . "\n\n" . 'wp example hello Newman', ) );


请注意,该属性将附加到从概要生成的选项的描述中,因此此参数非常适合添加用法示例。如果没有概要,将按原样使用该属性来提供描述。`longdesc``longdesc`

### [命令内部](#command-internals)

现在您知道如何注册命令,世界就是您的牡蛎。在回调中,命令可以做任何它想做的事情。

#### [接受参数](#accepting-arguments)

为了处理运行时参数,您必须向可调用对象添加两个参数:和 。`$args``$assoc_args`

function hello( $args, $assoc_args ) { /* Code goes here*/ }


`$args`变量将存储所有位置参数:

$ wp example hello Joe Doe


WP_CLI::line( $args[0] ); // Joe WP_CLI::line( $args[1] ); // Doe


`$assoc_args`变量将存储所有定义的参数,如或或`--key=value``--flag``--no-flag`

$ wp example hello --name='Joe Doe' --verbose --no-option


WP_CLI::line( $assoc_args['name'] ); // Joe Doe WP_CLI::line( $assoc_args['verbose'] ); // true WP_CLI::line( $assoc_args['option'] ); // false


此外,您还可以组合参数类型:

$ wp example hello --name=Joe foo --verbose bar


WP_CLI::line( $assoc_args['name'] ); // Joe WP_CLI::line( $assoc_args['verbose'] ); // true WP_CLI::line( $args[0] ); // foo WP_CLI::line( $args[1] ); // bar


#### [有效地重用 WP-CLI 内部 API](#effectively-reusing-wp-cli-internal-apis)

例如,假设您的任务是在多站点网络上查找所有未使用的主题 ([#2523](https://github.com/wp-cli/wp-cli/issues/2523))。如果您必须通过WordPress管理员手动执行此任务,则可能需要数小时甚至数天的努力。但是,如果您熟悉编写 WP-CLI 命令,则可以在 15 分钟或更短的时间内完成任务。

Here’s what such a command looks like:

/**

  • Find unused themes on a multisite network.
  • Iterates through all sites on a network to find themes which aren't enabled
  • on any site. */ $find_unused_themes_command = function() { $response = WP_CLI::launch_self( 'site list', array(), array( 'format' => 'json' ), false, true ); $sites = json_decode( $response->stdout ); $unused = array(); $used = array(); foreach( $sites as $site ) { WP_CLI::log( "Checking {$site->url} for unused themes..." ); $response = WP_CLI::launch_self( 'theme list', array(), array( 'url' => $site->url, 'format' => 'json' ), false, true ); $themes = json_decode( $response->stdout ); foreach( $themes as $theme ) { if ( 'no' == $theme->enabled && 'inactive' == $theme->status && ! in_array( $theme->name, $used ) ) { $unused[ $theme->name ] = $theme; } else { if ( isset( $unused[ $theme->name ] ) ) { unset( $unused[ $theme->name ] ); } $used[] = $theme->name; } } } WP_CLI\Utils\format_items( 'table', $unused, array( 'name', 'version' ) ); }; WP_CLI::add_command( 'find-unused-themes', $find_unused_themes_command, array( 'before_invoke' => function(){ if ( ! is_multisite() ) { WP_CLI::error( 'This is not a multisite installation.' ); } }, ) );

让我们浏览一下此命令用于实现其目标[的内部 API](https://make.wordpress.org/cli/handbook/internal-api/):

*   `WP_CLI::add_command()` ([文档](https://make.wordpress.org/cli/handbook/internal-api/wp-cli-add-command/))用于将命令注册到闭包。通过该参数,可以验证命令是否在多站点安装上运行,如果不是,则出错。`find-unused-themes``$find_unused_themes_command``before_invoke`
*   `WP_CLI::error()` ([文档](https://make.wordpress.org/cli/handbook/internal-api/wp-cli-error/))呈现格式良好的错误消息并退出。
*   `WP_CLI::launch_self()` ([文档](https://make.wordpress.org/cli/handbook/internal-api/wp-cli-launch-self/))最初生成一个获取所有网站列表的过程,然后用于获取给定网站的主题列表。
*   `WP_CLI::log()` ([文档](https://make.wordpress.org/cli/handbook/internal-api/wp-cli-log/))向最终用户呈现信息输出。
*   `WP_CLI\Utils\format_items()` ([文档](https://make.wordpress.org/cli/handbook/internal-api/wp-cli-utils-format-items/))在命令完成发现后呈现未使用主题的列表。

### [帮助渲染](#help-rendering)

命令的 PHPDoc(或注册的定义)是使用该命令呈现的。输出的顺序如下:`help`

1.  简短描述
2.  概要
3.  详细描述(选项、示例等)
4.  全局参数

[编写测试](#writing-tests)
----------------------

WP-CLI使用基于Behat的测试框架,您也应该使用它。Behat是WP-CLI命令的绝佳选择,因为:

*   编写新测试很容易,这意味着它们实际上会被编写出来。
*   测试与命令的交互方式与用户界面与命令的交互方式相同。

Behat 测试存在于项目的目录中。下面是一个来自以下示例:`features/``features/cli-info.feature`

Feature: Review CLI information

Scenario: Get the path to the packages directory Given an empty directory

When I run `wp cli info --format=json`
Then STDOUT should be JSON containing:
  """
  {"wp_cli_packages_dir_path":"/tmp/wp-cli-home/.wp-cli/packages/"}
  """

When I run `WP_CLI_PACKAGES_DIR=/tmp/packages wp cli info --format=json`
Then STDOUT should be JSON containing:
  """
  {"wp_cli_packages_dir_path":"/tmp/packages/"}
  """

功能测试通常遵循以下模式:

*   **鉴于**一些背景,
*   **当用户**执行特定操作时,
*   **那么**最终结果应该是 X(以及 Y 和 Z)。

相信?转到 [wp-cli/scaffold-package-command](https://github.com/wp-cli/scaffold-package-command) 开始。

[分配](#distribution)
-------------------

现在您已经生成了一个引以为豪的命令,是时候与世界分享它了。有两种常见的方法。

### [包含在插件或主题中](#include-in-a-plugin-or-theme)

共享WP-CLI命令的一种方法是将它们打包到您的插件或主题中。许多人通过基于常量的存在有条件地加载(和注册)命令来做到这一点。`WP_CLI`

if ( defined( 'WP_CLI' ) && WP_CLI ) { require_once dirname( FILE ) . '/inc/class-plugin-cli-command.php'; }


### [作为独立命令分发](#distribute-as-a-stand-alone-command)

独立的WP-CLI命令可以从任何git存储库,ZIP文件或文件夹安装。唯一的技术要求是包括有效的作曲家。带有自动加载声明的 JSON 文件。我们建议将项目明确区分为 WP-CLI 包。`"type": "wp-cli-package"`

下面是来自服务器命令的完整 composer.json 示例:

{ "name": "wp-cli/server-command", "description": "Start a development server for WordPress", "type": "wp-cli-package", "homepage": "https://github.com/wp-cli/server-command", "license": "MIT", "authors": [ { "name": "Package Maintainer", "email": "packagemaintainer@homepage.com", "homepage": "https://www.homepage.com" } ], "require": { "php": ">=5.3.29" }, "autoload": { "files": [ "command.php" ] } }


请注意声明,它加载 .`autoload``command.php`

将有效的 composer.json 文件添加到项目存储库后,WP-CLI 用户可以通过包管理器将其从您选择存储它的位置拉入。下面是存储位置的一些示例以及通过包管理器安装它的相应语法:

#### [Git 存储库](#git-repository)

要安装可在 git 存储库中找到的包,您可以向命令提供指向 git 存储库的 HTTPS 或 SSH 链接。`package install`

Installing the package using an HTTPS link

$ wp package install https://github.com/wp-cli/server-command.git

Installing the package using an SSH link

$ wp package install git@github.com:wp-cli/server-command.git


#### [压缩文件](#zip-file)

您可以通过提供命令的 ZIP 文件的路径来从该文件安装包。`wp package install`

Installing the package using a ZIP file

$ wp package install ~/Downloads/server-command-main.zip