If you haven’t been following this series, make sure you at least skim through WordPress Internals: How WordPress Boots Up and WordPress Internals: How WordPress Boots Up Part 2, where we went from the very moment an HTTP request hits the index.php front-facing WordPress file and up to the quite cumbersome but lighting fast bootstrap process that wp-settings.php leads and sustains.
This third part will deal with the more interesting parts, after the bootstrap routines, which will hopefully not bore you to death and provide some insight into how WordPress works from the inside, helping you understand and leverage all its internal power when developing themes and plugins.
So, wp-settings.php, which is required wp-config.php, which in turn is required by wp-load.php, which in turn is required by wp-blog-header.php, which in turn is required by index.php, which in turn is requested by our visitors returns control over to wp-blog-header.php. Remember how wp-blog-header.php seems to branch off when requiring
wp-load.php? Our previous post was dedicated to that branch. Now wp-blog-header.php is going to call the
This leads us to our next stop in this long journey to the center of WordPress – the
wp() function, which is defined in wp-includes/functions.php, so let’s open it up and see what happens exactly (it’s on line 1565 if you’re lost).
wp() brings in three global objects
$wp_the_query which are instances of the
$wp_the_query reference the same instance of
WP_Query as wp-settings.php set it up on line 229 –
$wp_query =& $wp_the_query. The comment above this assignment states that
$wp_query should be used instead of
$wp_the_query. I’m not sure as to why it is setup this way, the source code is sprinkled with both
$wp_the_query, yet there are only 4 assignments (2 of each) and they are limited to assigning themselves to one another.
wp-app.php:1068: $wp_query = $GLOBALS['wp_query']; wp-settings.php:229: $wp_query =& $wp_the_query; wp-includes/functions.php:1570: $wp_the_query = $wp_query; wp-settings.php:221: $wp_the_query = new WP_Query();
Back-compatibility? Caching? I can only guess for now, but if you do know please lend us an insight.
Anyways, back on track. The
$wp->main( $query_vars ); method is called with an empty
$query_vars string. This is what happens inside the
$this->init()sets up the current user using the
wp_get_current_user()function, defined in wp-includes/pluggable.php. This sets up the
$current_userglobal, an instance of the
$this->parse_request($query_args)which does all the hard work of providing a correct query by utilizing WordPress rewrite rules, the raw
$_GETserver variables (filtered by an allowed set of variables listed in
WP::$private_query_vars, which can be filtered with the
query_varsfilter to add/remove anything you want) to finally store a nice and clean query array inside its public
$query_varsproperty which can be accessed via the global
$wp->query_varsobject property. Neat huh?
$this->send_headers()prepares a list of headers to be sent out with the response. The X-Pingback, a set of no-cache headers if user is logged in or an error occurred, Content-Type and Last-Modified headers for feeds if ‘feed’ is inside the query variables, adds any additional headers by applying the
wp_headersfilter, and finally setting them as response headers using the PHP
header()function. At this point the headers have been set, and WordPress kindly lets you know about this by doing the
$this->query_posts()– this method sets the
queryproperty which is then utilized when interfacing with the celebrated WordPress Loop.
$this->handle_404()– sets the appropriate 404 or 200 headers based on whether
$wp_query->postsreturns more than 0 posts.
$this->register_globals()– extracts the query variables back into the global namespace and registers the
- One of the most used WordPress actions is fired off at this point – the
And it’s back to wp-blog.header.php into its final branch that loads up the WordPress theme. The wp-includes/template-loader.php file is required and here is what happens:
template_redirectaction is fired, giving plugins the chance to do something before the theme is loaded, possibly exiting so that when displaying the theme is not necessary around 40% of the theme loading time can be saved. Useful for plugins utilizing XHTTPRequests or handling RPC requests among everything else.
- If the request
is_trackback()appropriate actions are taken and the template loader returns.
- Next, if
WP_USE_THEMES(defined for the first time in index.php) is set to true a template is acquired via the use of the
get_???_template()functions, which were all defined inside wp-includes/theme.php. A long
iftree checks for various conditions using all sorts of
is_page()) and tries to get the appropriate template. The functions make sure that the highest priority template is loaded, taking into account child themes, missing files, filters, etc.
- If the
$templatevariable has been assigned a positive value, the template file is finally included.
And yes, control is returned to wp-blog-header.php, which returns control to index.php, which has no more code to execute. The original request is blessed with a response in under a couple of seconds (uncached, no fancy stuff), the visitor is probably happy and you are proud to be running WordPress and knowing most of the bare stuff that makes it tick when responding.
Our journey to the center of the WordPress core has come to an end. We’ve explored lots of the initialization and got to know some of WordPress more intimately. It may seem bloated, heavyweight to some, but others find exquisiteness in how it operates, geniality in the flexibility it provides and inspiration in how the small WordPress bits interact with one another under the unpredictable variability of circumstances to bring joy with each and every request. What do you think? After having seen how WordPress responds to the most basic request, is it too complex, too inflated?
Share some thoughts, ask questions via our comment section below, throw a tweet in our direction and stay tuned for more episodes of WordPress Internals and other great WordPress-related stuff. And don’t forget to let us know what part of WordPress you want us to dissect next.