* @return bool Always returns true.
$timestart = microtime( true );
* Retrieves or displays the time from the page start to when function is called.
* @global float $timestart Seconds from when timer_start() is called.
* @global float $timeend Seconds from when function is called.
* @param int|bool $display Whether to echo or return the results. Accepts 0|false for return,
* 1|true for echo. Default 0|false.
* @param int $precision The number of digits from the right of the decimal to display.
* @return string The "second.microsecond" finished time calculation. The number is formatted
* for human consumption, both localized and rounded.
function timer_stop( $display = 0, $precision = 3 ) {
global $timestart, $timeend;
$timeend = microtime( true );
$timetotal = $timeend - $timestart;
if ( function_exists( 'number_format_i18n' ) ) {
$r = number_format_i18n( $timetotal, $precision );
$r = number_format( $timetotal, $precision );
* Sets PHP error reporting based on WordPress debug settings.
* Uses three constants: `WP_DEBUG`, `WP_DEBUG_DISPLAY`, and `WP_DEBUG_LOG`.
* All three can be defined in wp-config.php. By default, `WP_DEBUG` and
* `WP_DEBUG_LOG` are set to false, and `WP_DEBUG_DISPLAY` is set to true.
* When `WP_DEBUG` is true, all PHP notices are reported. WordPress will also
* display internal notices: when a deprecated WordPress function, function
* argument, or file is used. Deprecated code may be removed from a later
* It is strongly recommended that plugin and theme developers use `WP_DEBUG`
* in their development environments.
* `WP_DEBUG_DISPLAY` and `WP_DEBUG_LOG` perform no function unless `WP_DEBUG`
* When `WP_DEBUG_DISPLAY` is true, WordPress will force errors to be displayed.
* `WP_DEBUG_DISPLAY` defaults to true. Defining it as null prevents WordPress
* from changing the global configuration setting. Defining `WP_DEBUG_DISPLAY`
* as false will force errors to be hidden.
* When `WP_DEBUG_LOG` is true, errors will be logged to `wp-content/debug.log`.
* When `WP_DEBUG_LOG` is a valid path, errors will be logged to the specified file.
* Errors are never displayed for XML-RPC, REST, `ms-files.php`, and Ajax requests.
* @since 5.1.0 `WP_DEBUG_LOG` can be a file path.
function wp_debug_mode() {
* Filters whether to allow the debug mode check to occur.
* This filter runs before it can be used by plugins. It is designed for
* non-web runtimes. Returning false causes the `WP_DEBUG` and related
* constants to not be checked and the default PHP values for errors
* will be used unless you take care to update them yourself.
* To use this filter you must define a `$wp_filter` global before
* WordPress loads, usually in `wp-config.php`.
* $GLOBALS['wp_filter'] = array(
* 'enable_wp_debug_mode_checks' => array(
* 'function' => function() {
* @param bool $enable_debug_mode Whether to enable debug mode checks to occur. Default true.
if ( ! apply_filters( 'enable_wp_debug_mode_checks', true ) ) {
error_reporting( E_ALL );
if ( WP_DEBUG_DISPLAY ) {
ini_set( 'display_errors', 1 );
} elseif ( null !== WP_DEBUG_DISPLAY ) {
ini_set( 'display_errors', 0 );
if ( in_array( strtolower( (string) WP_DEBUG_LOG ), array( 'true', '1' ), true ) ) {
$log_path = WP_CONTENT_DIR . '/debug.log';
} elseif ( is_string( WP_DEBUG_LOG ) ) {
$log_path = WP_DEBUG_LOG;
ini_set( 'log_errors', 1 );
ini_set( 'error_log', $log_path );
error_reporting( E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING | E_RECOVERABLE_ERROR );
* The 'REST_REQUEST' check here is optimistic as the constant is most
* likely not set at this point even if it is in fact a REST request.
if ( defined( 'XMLRPC_REQUEST' ) || defined( 'REST_REQUEST' ) || defined( 'MS_FILES_REQUEST' )
|| ( defined( 'WP_INSTALLING' ) && WP_INSTALLING )
|| wp_doing_ajax() || wp_is_json_request()
ini_set( 'display_errors', 0 );
* Sets the location of the language directory.
* To set directory manually, define the `WP_LANG_DIR` constant
* If the language directory exists within `WP_CONTENT_DIR`, it
* is used. Otherwise the language directory is assumed to live
function wp_set_lang_dir() {
if ( ! defined( 'WP_LANG_DIR' ) ) {
if ( file_exists( WP_CONTENT_DIR . '/languages' ) && @is_dir( WP_CONTENT_DIR . '/languages' )
|| ! @is_dir( ABSPATH . WPINC . '/languages' )
* Server path of the language directory.
* No leading slash, no trailing slash, full path, not relative to ABSPATH
define( 'WP_LANG_DIR', WP_CONTENT_DIR . '/languages' );
if ( ! defined( 'LANGDIR' ) ) {
// Old static relative path maintained for limited backward compatibility - won't work in some cases.
define( 'LANGDIR', 'wp-content/languages' );
* Server path of the language directory.
* No leading slash, no trailing slash, full path, not relative to `ABSPATH`.
define( 'WP_LANG_DIR', ABSPATH . WPINC . '/languages' );
if ( ! defined( 'LANGDIR' ) ) {
// Old relative path maintained for backward compatibility.
define( 'LANGDIR', WPINC . '/languages' );
* Loads the database class file and instantiates the `$wpdb` global.
* @global wpdb $wpdb WordPress database abstraction object.
function require_wp_db() {
require_once ABSPATH . WPINC . '/class-wpdb.php';
if ( file_exists( WP_CONTENT_DIR . '/db.php' ) ) {
require_once WP_CONTENT_DIR . '/db.php';
$dbuser = defined( 'DB_USER' ) ? DB_USER : '';
$dbpassword = defined( 'DB_PASSWORD' ) ? DB_PASSWORD : '';
$dbname = defined( 'DB_NAME' ) ? DB_NAME : '';
$dbhost = defined( 'DB_HOST' ) ? DB_HOST : '';
$wpdb = new wpdb( $dbuser, $dbpassword, $dbname, $dbhost );
* Sets the database table prefix and the format specifiers for database
* Columns not listed here default to `%s`.
* @global wpdb $wpdb WordPress database abstraction object.
* @global string $table_prefix The database table prefix.
function wp_set_wpdb_vars() {
global $wpdb, $table_prefix;
if ( ! empty( $wpdb->error ) ) {
$wpdb->field_types = array(
'term_taxonomy_id' => '%d',
'comment_post_ID' => '%d',
'comment_parent' => '%d',
$prefix = $wpdb->set_prefix( $table_prefix );
if ( is_wp_error( $prefix ) ) {
wp_load_translations_early();
/* translators: 1: $table_prefix, 2: wp-config.php */
__( '<strong>Error:</strong> %1$s in %2$s can only contain numbers, letters, and underscores.' ),
'<code>$table_prefix</code>',
'<code>wp-config.php</code>'
* Toggles `$_wp_using_ext_object_cache` on and off without directly
* @global bool $_wp_using_ext_object_cache
* @param bool $using Whether external object cache is being used.
* @return bool The current 'using' setting.
function wp_using_ext_object_cache( $using = null ) {
global $_wp_using_ext_object_cache;
$current_using = $_wp_using_ext_object_cache;
$_wp_using_ext_object_cache = $using;
* Starts the WordPress object cache.
* If an object-cache.php file exists in the wp-content directory,
* it uses that drop-in as an external object cache.
* @global array $wp_filter Stores all of the filters.
function wp_start_object_cache() {
static $first_init = true;
// Only perform the following checks once.
* Filters whether to enable loading of the object-cache.php drop-in.
* This filter runs before it can be used by plugins. It is designed for non-web
* runtimes. If false is returned, object-cache.php will never be loaded.
* @param bool $enable_object_cache Whether to enable loading object-cache.php (if present).
if ( $first_init && apply_filters( 'enable_loading_object_cache_dropin', true ) ) {
if ( ! function_exists( 'wp_cache_init' ) ) {
* This is the normal situation. First-run of this function. No
* caching backend has been loaded.
* We try to load a custom caching backend, and then, if it
* results in a wp_cache_init() function existing, we note
* that an external object cache is being used.
if ( file_exists( WP_CONTENT_DIR . '/object-cache.php' ) ) {
require_once WP_CONTENT_DIR . '/object-cache.php';
if ( function_exists( 'wp_cache_init' ) ) {
wp_using_ext_object_cache( true );
// Re-initialize any hooks added manually by object-cache.php.
$wp_filter = WP_Hook::build_preinitialized_hooks( $wp_filter );
} elseif ( ! wp_using_ext_object_cache() && file_exists( WP_CONTENT_DIR . '/object-cache.php' ) ) {
* Sometimes advanced-cache.php can load object-cache.php before
* this function is run. This breaks the function_exists() check
* above and can result in wp_using_ext_object_cache() returning
* false when actually an external cache is in use.
wp_using_ext_object_cache( true );
if ( ! wp_using_ext_object_cache() ) {
require_once ABSPATH . WPINC . '/cache.php';
require_once ABSPATH . WPINC . '/cache-compat.php';
* If cache supports reset, reset instead of init if already
* initialized. Reset signals to the cache that global IDs
* have changed and it may need to update keys and cleanup caches.
if ( ! $first_init && function_exists( 'wp_cache_switch_to_blog' ) ) {
wp_cache_switch_to_blog( get_current_blog_id() );
} elseif ( function_exists( 'wp_cache_init' ) ) {
if ( function_exists( 'wp_cache_add_global_groups' ) ) {
wp_cache_add_global_groups(
wp_cache_add_non_persistent_groups( array( 'counts', 'plugins', 'theme_json' ) );
* Redirects to the installer if WordPress is not installed.
* Dies with an error message when Multisite is enabled.
function wp_not_installed() {
if ( is_blog_installed() || wp_installing() ) {
wp_die( __( 'The site you have requested is not installed properly. Please contact the system administrator.' ) );
require ABSPATH . WPINC . '/kses.php';
require ABSPATH . WPINC . '/pluggable.php';
$link = wp_guess_url() . '/wp-admin/install.php';
* Retrieves an array of must-use plugin files.
* The default directory is wp-content/mu-plugins. To change the default
* directory manually, define `WPMU_PLUGIN_DIR` and `WPMU_PLUGIN_URL`
* @return string[] Array of absolute paths of files to include.
function wp_get_mu_plugins() {
if ( ! is_dir( WPMU_PLUGIN_DIR ) ) {
$dh = opendir( WPMU_PLUGIN_DIR );
while ( ( $plugin = readdir( $dh ) ) !== false ) {
if ( str_ends_with( $plugin, '.php' ) ) {
$mu_plugins[] = WPMU_PLUGIN_DIR . '/' . $plugin;
* Retrieves an array of active and valid plugin files.