Skip to content

Write custom WP-CLI commands

WP-CLI commands can be created and run using VIP-CLI on the VIP platform. The best practices outlined here are an extension of the developer documentation in the WP-CLI Handbook and the Commands Cookbook.

A custom WP-CLI command is registered using WP_CLI::add_command(), which accepts 3 parameters.

  • The first argument $name is the name of the command to call inside the wp CLI namespace.
    For example, to build a command wp sample the command would be registered with the the $name 'sample'.
  • The second argument $callable is a callable item, like a function, closure, callable class or anonymous function.
  • The optional third argument $args is used to define other characteristics of the command.

Write a function based command

This example shows a basic registration for a custom command wp sample.

<?php
function sample_command( $args ) {
    WP_CLI::success( 'Thank you for running the sample command.' );
}
WP_CLI::add_command( 'sample', 'sample_command' );

More examples and guidance for custom WP-CLI commands can be found in the WP-CLI Commands Cookbook.

Write class-based commands

Registering a PHP class as the $callable second argument for WP_CLI::add_command() can be done in a variety of ways.

The PHP Magic Method __invoke() can be used to pass either the class name or an instance of the class. Both examples of registering the command below are functionally equivalent methods to register the command wp env-check.

<?php
class Example_Command {
    protected $environment;

    public function __construct( ) {
        $this->environment = wp_get_environment_type();
    }
	
    public function __invoke( $args ) {
        WP_CLI::log( sprintf( 'The current environment is: %s', $this->environment ) );
    }
}
// 1. Register the instance for the callable parameter.
$instance = new Example_Command();
WP_CLI::add_command( 'env-check', $instance );

// 2. Register object as a function for the callable parameter.
WP_CLI::add_command( 'env-check', 'Example_Command' );

Subcommand support

To register a command that supports multiple subcommands, use a class with methods that match the subcommand names. The following is an example that implements subcommands: wp example environment and wp example subcommand.

<?php
class Example_Command {
    
	// Usage: wp example environment
	public function environment( $args ) {
        WP_CLI::log( sprintf( 'Environment: %s', wp_get_environment_type() ) );
	}
	
	// Usage: wp example subcommand
	public function subcommand() {
        WP_CLI::log( sprintf( 'You have run a subcommand' ) );
	}
}
WP_CLI::add_command( 'example', 'Example_Command' );

Handle CLI arguments

When run, a WP-CLI command passes 2 arguments to the callable handler, $args and $assoc_args. Both are iterators, or arrays, of parameters that are passed to the WP-CLI command. $args is an iterator of the unnamed, or positional arguments and $assoc_args is an iterator of named, or associative arguments. Associative arguments are sometimes referred to as “flags”.

By using the wp_parse_args() function the default values for optional parameters in a command’s function can be set.

function example_command( $args,  $assoc_args ) {
	$assoc_args = wp_parse_args(
		$assoc_args,
		array(
			'dry-run'   => true,
			'format'    => 'table'
			'post-meta' => 'some_default_post_meta'
		)
	);
}

WP-CLI output functions

The WP-CLI natively supports a variety of methods for outputting to the screen while running a WP-CLI command.

The most commonly used output methods are WP_CLI::success() and WP_CLI::error() to indicate the final result of an action, and WP_CLI::log() for informational output while the command is running.

Using WP_CLI::error() will interrupt the command by causing the script to exit , and will prevent the rest of the command from continuing.  If only the error-like condition that the script encountered without stopping the command is needed, use WP_CLI::log() or WP_CLI::warning().

CommandDescription
WP_CLI::log()Display informational message without prefix, or discarded when --quiet argument is supplied
WP_CLI::line()Display informational message without prefix, and ignores --quiet argument
Note: Using WP_CLI::log() is typically recommended;
WP_CLI::line() is included for historical compatibility.
WP_CLI::debug()Display debug message prefixed with “Debug: ” when --debug argument is supplied
WP_CLI::warning()Display warning message prefixed with “Warning: “
WP_CLI::success()Display success message prefixed with “Success: “
WP_CLI::error()Display error message prefixed with “Error: “, and exits script

Include only when the WP-CLI is being used

It is important that WP_CLI::add_command() be wrapped inside a check that the constant WP_CLI is defined, and evaluates to true, in order to prevent fatal errors. This check is also the best way to identify if the code is being executed via the WP-CLI.

If the custom WP-CLI command is part of a theme, the check can be added to the theme’s functions.php file like this example:

<?php
if ( defined( 'WP_CLI' ) && WP_CLI ) {
	include_once MY_THEME_DIR . '/inc/class-mycommand-cli.php';
}

If the custom WP-CLI command is included in a plugin or as part of a Must Use script, this snippet may be more appropriate:

<?php
if ( defined( 'WP_CLI' ) && WP_CLI ) {
	include_once __DIR__ . '/inc/class-mycommand-cli.php';
}

Both of the above examples assume both the WP_CLI::add_command() to register the command and the associated function or class would be defined in the class-mycommand.cli.php file.

Optionally, this check can be wrapped around the WP_CLI::add_command() function to make the class or function available but only register the command when the WP-CLI is being used.

<?php
if ( defined( 'WP_CLI' ) && WP_CLI ) {
	WP_CLI::add_command( 'my-command', 'MyCommand' );
}

Last updated: December 26, 2023

Relevant to

  • WordPress