SHORTINIT constant: WordPress environment with minimal load
I was worried about a question: how can I use $wpdb
object and site database with which I work, but with minimal loading of WP environment. Sometimes it is necessary, when using Ajax to get or write data to the database and nothing else:
- do not need filters.
- do not need to check for user authorization.
- do not need WordPress functions
- do not need other checks and a bunch of loaded functions.
In general, when we don't need anything other than the ability to communicate with the database using the usual WordPress methods.

You can solve such a problem by reading the database connection data from the file wp-config.php
and connect to the database separately. But it's not very convenient and would require extra code, which in fact is already in the files of WordPress.
Since version 3.4, the developers of WordPress have taken care of this and added a SHORTINIT
constant in wp-settings.php:
// Stop the main load of WordPress if we only want the base. if ( SHORTINIT ) return false;
It works like this:
// specify that we need a minimum of WP define('SHORTINIT', true); // Loading the WordPress environment // WP does some checks and loads only the essentials to connect to the database require_once( $_SERVER['DOCUMENT_ROOT'] . '/wp-load.php' ); // Here we can communicate with the database. // But practically no WP functions will work. // Global variables $wp, $wp_query, $wp_the_query are not set. global $wpdb; $result = $wpdb->get_results( "SELECT post_title FROM $wpdb->posts WHERE post_type='post'" ); if( $result ){ foreach( $result as $post ){ echo "$post->post_title <br>"; } }
Concrete numbers
To see how initializations with and without SHORTINIT differ. I measured: the number of SQL queries, the time to execute the code and the memory used. Here's what came up:
require_once( $_SERVER['DOCUMENT_ROOT'] . '/wp-load.php' ); // 5 SQL in 0.1 sec. Memory: 14.92 mb define( 'SHORTINIT', true ); require_once( $_SERVER['DOCUMENT_ROOT'] . '/wp-load.php' ); // 0 SQL in 0.02 sec. Memory: 2.35 mb
Таким образом SHORTINIT, грубо, по всем параметрам снижает нагрузку в 5 раз. Неплохо!
What works with SHORTINIT
When using SHORTINIT
the filter system: apply_filters() do_action() already works. The filters are basic (file: /wp-includes/default-filters.php). Those that you specified in functions.php
of your theme and many others will not work.
None of the usual functions: esc_attr(), is_single(), the_content(), get_permalink() etc. will work. Here are all the functions that are plugged in - see /wp-settings.php:
Include files required for initialization.
- /wp-includes/class-wp-paused-extensions-storage.php
- /wp-includes/class-wp-fatal-error-handler.php
- /wp-includes/class-wp-recovery-mode-cookie-service.php
- /wp-includes/class-wp-recovery-mode-key-service.php
- /wp-includes/class-wp-recovery-mode-link-service.php
- /wp-includes/class-wp-recovery-mode-email-service.php
- /wp-includes/class-wp-recovery-mode.php
- /wp-includes/error-protection.php
- /wp-includes/default-constants.php
- /wp-includes/plugin.php
If the WP_CACHE constant is enabled:
/wp-content/advanced-cache.php
Load early WordPress files.
- /wp-includes/class-wp-list-util.php
- /wp-includes/formatting.php
- /wp-includes/meta.php
- /wp-includes/functions.php
- /wp-includes/class-wp-meta-query.php
- /wp-includes/class-wp-matchesmapregex.php
- /wp-includes/class-wp.php
- /wp-includes/class-wp-error.php
- /wp-includes/default-filters.php
Loads for multisite:
- /wp-includes/class-wp-site-query.php
- /wp-includes/class-wp-network-query.php
- /wp-includes/ms-blogs.php
- /wp-includes/ms-settings.php
Authorization with SHORTINIT
Example of checking authorization and getting all user rights with SHORTINIT
:
<?php // specify that we need a minimum from WP define( 'SHORTINIT', true ); // Loading the WordPress environment require_once( $_SERVER['DOCUMENT_ROOT'] . '/wp/wp-load.php' ); // A shortened version of wp_hash from pluggable.php function wp_hash( $data ){ $salt = LOGGED_IN_KEY . LOGGED_IN_SALT; return hash_hmac( 'md5', $data, $salt ); } function hash_token( $token ){ if( function_exists( 'hash' ) ){ return hash( 'sha256', $token ); } else{ return sha1( $token ); } } function curr_user_can( $capability ){ global $all_caps; return isset( $all_caps[ $capability ] ) && $all_caps[ $capability ]; } function get_curr_user_can(){ global $wpdb; $_options = $wpdb->get_results( " SELECT `option_name`, `option_value` FROM $wpdb->options WHERE `option_name` IN ('siteurl', '{$wpdb->prefix}user_roles') ", 'OBJECT_K' ); if( ! $_options ){ return [ 'error', 'Options not found' ]; } $_c_hash = md5( $_options['siteurl']->option_value ); if( ! isset( $_COOKIE[ "wordpress_logged_in_$_c_hash" ] ) ){ return [ 'error', 'No cookies.' ]; } $cookie = $_COOKIE[ "wordpress_logged_in_$_c_hash" ]; $cookie_elements = explode( '|', $cookie ); if( count( $cookie_elements ) !== 4 ){ return [ 'error', 'Cookie is broken' ]; } $username = $cookie_elements[0]; $expiration = $cookie_elements[1]; $token = $cookie_elements[2]; $hmac = $cookie_elements[3]; if( $expiration < time() ){ return [ 'error', 'Session time has expired' ]; } $user = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->users WHERE `user_login`=%s", $username ), 'OBJECT' ); if( ! $user ){ return [ 'error', 'There is no such user' ]; } $pass_frag = substr( $user->user_pass, 8, 4 ); $key = wp_hash( $username . '|' . $pass_frag . '|' . $expiration . '|' . $token ); $algo = function_exists( 'hash' ) ? 'sha256' : 'sha1'; $hash = hash_hmac( $algo, $username . '|' . $expiration . '|' . $token, $key ); if( ! hash_equals( $hash, $hmac ) ){ return [ 'error', 'Hash is not equivalent to' ]; } $user_options = $wpdb->get_results( " SELECT `meta_key` ,`meta_value` FROM $wpdb->usermeta WHERE `user_id` = $user->ID AND `meta_key` IN ( 'session_tokens', '{$wpdb->prefix}capabilities' ) ", OBJECT_K ); if( ! $user_options ){ return [ 'error', 'User options are not set' ]; } $sessions = unserialize( $user_options['session_tokens']->meta_value ); $verifier = hash_token( $token ); if( ! isset( $sessions[ $verifier ] ) ){ return [ 'error', 'No authorization token' ]; } if( $sessions[ $verifier ]['expiration'] < time() ){ return [ 'error', 'Session time has expired' ]; } $role_caps = unserialize( $_options[ $wpdb->prefix . 'user_roles' ]->option_value ); $user_caps = unserialize( $user_options[ $wpdb->prefix . 'capabilities' ]->meta_value ); $all_caps = []; foreach( $user_caps as $key => $value ){ if( isset( $role_caps[ $key ] ) && $value ){ $all_caps = array_merge( $all_caps, $role_caps[ $key ]['capabilities'], true ); } else{ $all_caps[ $key ] = $value; } } return [ 'success', $all_caps ]; }