This page contains some history on various implementation details of WP-CLI.
On a normal web request, your web server calls the index.php
file in the root of the web directory to bootstrap the WordPress load process:
<?php
/**
* Front to the WordPress application. This file doesn't do anything, but loads
* wp-blog-header.php which does and tells WordPress to load the theme.
*
* @package WordPress
*/
/**
* Tells WordPress to load the WordPress theme and output it.
*
* @var bool
*/
define('WP_USE_THEMES', true);
/** Loads the WordPress Environment and Template */
require( dirname( __FILE__ ) . '/wp-blog-header.php' );
You'll notice index.php
calls wp-blog-header.php
, which then calls wp-load.php
, which then calls wp-config.php
, which then calls wp-settings.php
.
This last file, wp-settings.php
, is WordPress' primary bootstrap file. It loads your plugins, active theme, and calls the init
action.
On the command line, WP-CLI follows a similar process to bootstrap WordPress. However, instead of loading index.php
, using the wp
command starts with this:
<?php
// Can be used by plugins/themes to check if WP-CLI is running or not
define( 'WP_CLI', true );
define( 'WP_CLI_VERSION', trim( file_get_contents( WP_CLI_ROOT . '/VERSION' ) ) );
define( 'WP_CLI_START_MICROTIME', microtime( true ) );
// Set common headers, to prevent warnings from plugins
$_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.0';
$_SERVER['HTTP_USER_AGENT'] = '';
$_SERVER['REQUEST_METHOD'] = 'GET';
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
include WP_CLI_ROOT . '/php/utils.php';
include WP_CLI_ROOT . '/php/dispatcher.php';
include WP_CLI_ROOT . '/php/class-wp-cli.php';
include WP_CLI_ROOT . '/php/class-wp-cli-command.php';
\WP_CLI\Utils\load_dependencies();
WP_CLI::get_runner()->start();
WP-CLI includes a good amount of setup code prior to calling wp-settings.php
. Its bootstrapping process is different than a web request in a couple of notable ways.
Rather than calling wp-config.php
directly, WP-CLI gets the contents of wp-config.php
, parses out the require_once ABSPATH . 'wp-settings.php';
statement, and loads the constants into scope with eval()
. Read "How WP-CLI loads WordPress" for a narrative on the historical reasons. After that, WP-CLI used a custom wp-settings-cli.php
until v0.24.0 [#2278], but parsing wp-config.php
was kept for backwards compatibility purposes. See also #1631.
WP-CLI loads WordPress with the WP_CLI::get_runner()->load_wordpress()
method, meaning WordPress plugins and themes aren't loaded in global scope. Any global variables used in plugins or themes need to be explicitly globalized. See #2089 for the history of this decision.
Once WP_CLI::get_runner()->load_wordpress()
calls wp-settings.php
, WordPress handles the rest of the bootstrap process.
The wp help <command>
has been through several incarnations.
Since WP-CLI 0.3, it invoked a static help()
method in the command class, if it existed. (48a8887d)
Since WP-CLI 0.6, it looked for a <command>.1
ROFF file and displayed it using man
. The ROFF file was compiled from a corresponding <command>.txt
markdown file and from PHPDoc metadata. (#24).
Since WP-CLI 0.11, it generates the help text on the fly. (#548)
Most WP-CLI commands perform administrative actions and they need access to code defined in wp-admin/includes
. This code can be loaded on-demand or preemptively.
The question is: should the WP_ADMIN
constant be set to true
or false
?
Initially, WP-CLI just loaded the wp-admin code and didn't mess with the WP_ADMIN constant at all.
Then, it sort of pretended it was doing a front-end page load, for doing integration testing (#69). [1]
Then it pretended it was loading wp-admin, to side-step caching plugins (#164).
Then it stopped pretending it was loading wp-admin (#352), because we found a better way to side-step caching plugins. [2]