我有时间的时候,翻译一下。
I began learning about WordPress by building themes and reading through the multitude of awesome tutorials posted across the net. A lot was learned through trial and error, and a lot was learned from copying and pasting. However, there is one topic for which I have yet to find comprehensive information: the WordPress initialization process. I mean from start to finish, how does the WordPress core take the initial page request and give back such beautiful web pages? It’s time to take the plunge and actually step through the WordPress core, file by file, so I can get a better understanding of how our favorite personal publishing platform initializes itself and then displays my content, all of our content, for the world to see. I hope this post will serve not only as a place that I can return to as a reference but also as a place for all of you to turn to when you need a refresher on the inner workings of the WordPress core structure, or if you’re just starting out and need a better understanding of what WordPress is doing with your theme and your code. Let’s get started…
This post is based on the WordPress trunk code base. All of the links to Core Trac source code point to the trunk version of that code. I’ve done this because the WordPress core will change faster than I can keep this post updated, so following the links will always take you to the latest version of the relevant source, regardless of whether or not the content of this article has been updated. The downside to this decision is that you may follow a link that does not accurately reflect the code base for your version of WordPress. If you need to reference the core code base of a previous version of WordPress, the information in this post will at the very least get you close.
Update: On January 29, 2013 I reviewed the links and content in this post and updated it to reflect changes to the current version of WordPress; which at the time of the update was v3.5.1.
All of the magic flowing out of your server starts with a single file: index.php
. This simple file handles the initial request each and every time a page is loaded from your site. It serves two main functions. First it defines a constant named 'WP_USE_THEMES'
and sets it’s value to true. This tells the WordPress core that your site should use the active theme to display the pages it’s serving. Next it requires a file named wp-blog-header.php
. This file sits in the root directory of your site with index.php
.
wp-blog-header
is singularly responsible for three fundamental processes during the initialization of WordPress. First it requires a file named wp-load.php
, then it executes the function wp()
and finally it requires a file named template-loader.php
. wp-load.php
is also located in the root directory with index.php
and wp-blog-header.php
. The wp()
function is defined in /wp-includes/functions.php
. template-loader.php
also resides in the /wp-includes
directory with functions.php
. We will get to the wp-includes
directory in a little bit. We first have to step through the responsibilities of wp-load
and the files that it requires.
wp-load
has a simple yet extremely important role in WordPress’ initialization. It starts by setting a constant named 'ABSPATH'
to the root directory of your WordPress install. This constant is used extensively throughout the remainder of the initialization process to easily and consistently refer to config files relative to your root directory.wp-load
completes its work by loading wp-config.php
. Most of us should be at least a little familiar with this file. It wasn’t too long ago that manual editing of your wp-config
was still a requirement during the install process. Today we all enjoy an automatedwp-config
setup as long as our server’s user permissions are configured correctly.wp-load
actually runs through some checks to determine where your wp-config
file is located. This is because you can keep your wp-config
file outside of your root install directory. I’m not sure why you would but I assume it has a lot to do with security. If any one does know, please explain in the comments. If wp-load
fails to find a config file then it throws you a friendly error message with a button to create one.
If wp-load
successfully located your wp-config
file then this step uses that information to set the last bit of configuration settings before continuing with loading up the WordPress core. The comments at the top of wp-config
sum this step up quite nicely “This file has the following configurations: MySQL settings, Table Prefix, Secret Keys, WordPress Language, and ABSPATH“. I can’t put it any more succinctly than that. After wp-config
is parsed WordPress has all the information it needs to securely access your database and load your content. I’m not sure why ABSPATH
is checked again but it is, it’s the last line of code before ALL the fun begins. The final line of wp-config
requires wp-settings.php
which is responsible for loading the lion’s share of WordPress.
Finally some action! Up until now we’ve been wandering through mundane information collection. wp-settings.php
starts off by defining a new constant named'WPINC'
. This constant points to the /wp-includes
directory that was mentioned above. The majority of the predefined functions that WordPress needs for initialization are defined in this directory’s files. After defining WPINC
it requires three files from that directory, load.php
, default-constants.php
and version.php
. It’s important to remember that WordPress is not actually executing these functions. They are being included using the PHP function require()
, which makes their contents available to WordPress’ execution environment so the functions they contain can be called when they’re needed. load.php
includes the following functions that are required to properly setup WordPress:
wp_unregister_GLOBALS()
wp_fix_server_vars()
wp_check_php_mysql_versions()
wp_favicon_request()
wp_maintenance()
timer_start()
timer_stop()
wp_debug_mode()
wp_set_lang_dir()
require_wp_db()
wp_set_wpdb_vars()
wp_start_object_cache()
wp_not_installed()
wp_get_mu_plugins()
wp_get_active_and_valid_plugins()
wp_set_internal_encoding()
wp_magic_quotes()
shutdown_action_hook()
wp_clone()
is_admin()
is_blog_admin()
is_network_admin()
is_user_admin()
is_multisite()
get_current_blog_id()
wp_load_translations_early()
Once those essential functions have been loaded wp-settings
loads six more functions from default-constants.php
that will be used to ensure that the global environment for further initialization can be configured properly. The list below outlines these six functions and the constants they define.
wp_initial_constants()
WP_MEMORY_LIMIT
WP_MAX_MEMORY_LIMIT
$blog_id
WP_CONTENT_DIR
WP_DEBUG
WP_DEBUG_DISPLAY
WP_DEBUG_LOG
WP_CACHE
MEDIA_TRASH
SHORTINIT
MINUTE_IN_SECONDS
HOUR_IN_SECONDS
DAY_IN_SECONDS
WEEK_IN_SECONDS
YEAR_IN_SECONDS
wp_plugin_directory_constants()
WP_CONTENT_URL
WP_PLUGIN_DIR
WP_PLUGIN_URL
PLUGINDIR
WPMU_PLUGIN_DIR
WPMU_PLUGIN_URL
MUPLUGINDIR
wp_cookie_constants()
COOKIEHASH
USER_COOKIE
PASS_COOKIE
AUTH_COOKIE
SECURE_AUTH_COOKIE
LOGGED_IN_COOKIE
TEST_COOKIE
COOKIEPATH
SITECOOKIEPATH
ADMIN_COOKIE_PATH
PLUGINS_COOKIE_PATH
COOKIE_DOMAIN
wp_ssl_constants()
FORCE_SSL_ADMIN
FORCE_SSL_LOGIN
wp_functionality_constants()
AUTOSAVE_INTERVAL
EMPTY_TRASH_DAYS
WP_POST_REVISIONS
WP_CRON_LOCK_TIMEOUT
wp_templating_constants()
TEMPLATEPATH
STYLESHEETPATH
WP_DEFAULT_THEME
Finally version.php
is loaded which provides the following six variables:
$wp_version
$wp_db_version
$tinymce_version
$manifest_version
$required_php_version
$required_mysql_version
Now we’re cookin’!! The next 40 lines of code in wp-settings
call many of the functions included above. wp_initial_constants()
is run to setup memory, debug and caching constants; wp_check_php_mysql_versions()
makes sure that we’re running the minimum required versions of both PHP and MySQL; magic quotes are disabled because they will be added later; the default timezone is set; thewp_unregister_GLOBALS()
function is executed to disable PHP’s register globals setting; wp_fix_server_vars()
fixes various $_SERVER related problems across different hosts; wp_favicon_request()
ensures that the entire WordPress core isn’t loaded when only a favicon is being requested; wp_maintenance()
(a very cool function) checks to see if there is a .maintenance file in your ABSPATH
that was created less than 10 minutes ago, if there is it displays a default maintenance message that can be overridden by placing a custom maintenance.php
file in your /wp-content
directory; timer_start()
loads the timer; wp_debug_mode()
checks to see if debugging is enabled and turns on PHP’s error reporting if it is; the WP_CACHE
constant is checked and if it returns true then /wp-content/advanced-cache.php
is included; and finallywp_set_lang_dir()
sets the path to the language files.
The WP_CACHE
constant is used by 3rd party caching solutions like W3TC, WP Super Cache or Batcache. If WP_CACHE
returns true then advanced-cache.php
acts as the “bootstrapper” to load the caching engine you’re using (thanks to Mark Jaquith for that info).
At this point we have a pretty solid foundation for WordPress to build the rest of it’s initialization on top of. Now it’s time to load some the core files that provide WordPress’ true functionality. Next up wp-settings
requires five more files that it classifies as “early WordPress files”. They are compat.php, functions.php, class-wp.php, class-wp-error.php and plugin.php
. All of these are located in the /wp-includes
directory. While these may be early WordPress files they shouldn’t be underestimated. A tremendous amount of the functionality we expect from WordPress is provided in these five files. They are long and complex, functions.php
alone is over 4,500 lines! I am not going to go into the details of each file’s functions the same way I did above. I will, in future posts, address each of these files individually to give them the attention they deserve. I am after all writing this post (and future posts) to learn more about the core myself. The descriptions below have been taken directly from the source code comments on Trac. It’s more important for this post to focus on the overall initialization of WordPress so I’ll just outline these functions here:
compat.php
functions.php
class-wp.php
class-wp-error.php
plugin.php
mo.php
Now that the baseline functionality of the above files has been loaded wp-settings
moves on to call three more of the functions that were included in wp-load
above. Firstrequire_wp_db()
is called to load the DB class and set up the global $wpdb
object. It accomplishes this by requiring /wp-includes/wp-db.php
and then /wp-content/db.php
if it exists. wp-db.php
is another one of those files with over 1,000 lines of code. I will in the future dedicate a post to it alone. For the purposes of this article it’s only important to understand that wp-db.php
is an abstract class file for accessing a MySQL database. The reason that require_wp_db()
tries to require /wp-content/db.php
is because you can define your own database class to access your WordPress database by extending wp-db.php
and placing that code into the /wp-content/db.php
file. require_wp_db()
finishes up by creating the $wpdb
object using the database credentials defined in your wp-config
file. Next wp_set_wpdb_vars()
furthers the setup of the $wpdb
object by setting the field types for the table columns and the table prefix. The $table_prefix
variable defined in wp-config
is added to the$GLOBALS[]
array just prior to this step so WordPress knows exactly which tables it can access. Finally, wp_start_object_cache()
is called. It’s a little similar torequire_wp_db()
in that it’s responsible for loading an abstract class file. In this case its the WordPress Object Cache API. This class is responsible for caching database objects in memory to speed up frequent queries sent to the database.wp_start_object_cache()
first checks to see if there is a file named /wp-content/object-cache.php
because (like /wp-content/db.php
) you can define your own object cache file or class. If wp_start_object_cache()
finds /wp-content/object-cache.php
then WordPress’ internal object cache WILL NOT be loaded. If there is no /wp-content/object-cache.php
then the default cache filecache.php
is loaded.
Next up the default-filters.php
is required from the /wp-includes
directory. Thedefault-filters.php
file adds many (but not all) of the default filters and actions to the WordPress Hooks system. This file goes hand-in-hand with plugin.php
that was loaded above. Together these two files prepare the WordPress Plugin API. Anyone interested in plugin development should read through the Plugin API on the codex and have at least these two files open while reading it.
I’m going to group the next 17 lines of code together because after they’re executed we’ll be about halfway through wp-settings.php
and moving into loading a huge chunk of the WordPress core files and functionality. After default-filters.php
is loaded wp-settings
checks to see if we are running multisite. If we are then it loadsms-blogs.php
and ms-settings.php
from /wp-includes
. These two files act like wp-settings.php
but handle setup specific to sites that have MultiSite enabled in wp-config.php
. I don’t have any experience with MultiSite at this time but I plan on researching it in the future. At that time I will post an article similar to this one that concentrates on how multisite is initialized. Next, the value of SHORTINIT
is evaluated and if it’s true then initialization is halted at this point. This constant was defined in thewp_initial_constants()
function declared in default-constants.php
above. In that file, it’s default value is set set to false. There may be times that you need access to WordPress without loading all of it’s functionality, e.g. using it as a file serving proxy in MultiSite mode. Setting this constant to true allows you to halt initialization and only use the limited functionality loaded up to this point (thanks again to Mark Jaquith for this info). An additional file related to localization and translation: /wp-includes/l10n.php
, is required next and finally wp_not_installed()
is called to run the installer if we’ve reached this point and WordPress hasn’t been installed. This function was defined in load.php
and runs a few checks to see if certain variables and functions have been defined. If they haven’t, that means WordPress isn’t installed and the initialization process dies; at which point you are redirected to the installer /wp-admin/install.php
.
With those 17 lines of code out of the way wp-settings
moves on to loading the majority of the remaining core files. The following list is long and each file listed is even longer. Just as above, I am going to list them with brief descriptions and link to each file on Trac. Many of the following files deserve their own posts and I will tackle them as time permits. These 40 files constitute the majority of WordPress’ core functionality.
class-wp-walker.php
class-wp-ajax-response.php
formatting.php
capabilities.php
query.php
theme.php
class-wp-theme.php
template.php
user.php
meta.php
general-template.php
link-template.php
author-template.php
post.php
post-template.php
post-thumbnail-template.php
functions.php
must call add_theme_support( 'post-thumbnails' )
to use these.category.php
category-template.php
comment.php
comment-template.php
rewrite.php
feed.php
bookmark.php
bookmark-template.php
kses.php
cron.php
deprecated.php
script-loader.php
taxonomy.php
update.php
canonical.php
shortcodes.php
class-wp-embed.php
media.php
http.php
class-http.php
widgets.php
functions.php
file so easy.nav-menu.php
nav-menu-template.php
admin-bar.php
Note: If you’d like to read a little more about the inner workings of the Admin Bar (now officially called the Toolbar), check out my first freelance article over at WP Smashing Magazine: Inside The WordPress Toolbar.
Just from reading through these files one at a time I estimate that roughly 75% of the WordPress core has been loaded and we’re about half-way through the wp-settings
file. After all the require()
statements above wp-settings
does another check to see if we’re running multisite. If we are then it requires three additional files: ms-functions.php
, ms-default-filters.php
and ms-deprecated.php
. These are the MultiSite (formerly WordPress MU) versions of some of the files loaded above. After this check for MultiSite the function wp_plugin_directory_constants()
, which was defined in default-constants.php
, is executed. It sets up seven constants for plugins to use. Now that those constants have been created a foreach()
loop is run to include what are known as “must use” plugins. Back in load.php
a function namedwp_get_mu_plugins()
was defined. That function reads the location of theWPMU_PLUGIN_DIR
constant (which by default is set to /wp-content/mu-plugins
) and loads any plugins that it finds. Once that’s done there is another check to see if we’re running MultiSite. If we are then another foreach()
loop is executed to include thewp_get_active_network_plugins()
function. This function is defined in ms-load.php
and loads any MultiSite related plugins that are needed now from the WP_PLUGIN_DIR
constant, which by default is set to the wp-content/plugins
directory. ms-load.php
was included by the ms-settings.php
file. Now that the majority of the Plugin API has been setup the do_action( 'muplugins_loaded' )
hook is executed.
wp-settings
then moves on to call two more of the functions defined in default-constants.php
. wp_cookie_constants()
and wp_ssl_constants()
are responsible for guaranteeing that we have unique hashes for our cookies and whether or not to force admin and login SSL connections respectively. Once the cookies and SSL settings have been set the file vars.php
is required. This is actually a really cool file and I had no idea that this functionality existed in WordPress until I popped it open. vars.php
starts by setting the $pagenow
variable which always holds the location of the page that’s currently being viewed. After that it tests to see what browser is being used to view the page and stores that in one of a series of nine possible variables: $is_lynx
,$is_gecko
, $is_winIE
, $is_macIE
, $is_opera
, $is_NS4
, $is_safari
, $is_chrome
or$is_iphone
. How ’bout them apples!! If you’ve ever wanted to serve custom content to your visitors based on their browser from inside your template files these variables allow you to do just that. After the browser detection, vars.php
runs a few checks to determine what server software WordPress is running on, either Apache or IIS. Finally, it finishes up by setting one final variable: $is_mobile
. The variable is a boolean value (true|false) which will be set to true if the value of$_SERVER['HTTP_USER_AGENT']
matches any of the most common mobile browsers. Pretty fun stuff from a file of only 97 lines!
Up next wp-settings
fires off two more functions. create_initial_taxonomies()
(which is defined in taxonomies.php
) and create_initial_post_types()
(which is defined in post.php
). The first sets up and initializes the default WordPresstaxonomies and the second sets up the default post types (post, page, etc.). There is a warning in wp-settings
alerting all you developers out there that the defaults in these two files will be run again on the init hook that executes at the end of wp-settings
. Taxonomies are how WordPress organizes information internally. We are all familiar with the two most notable taxonomies already: categories and tags. Custom taxonomies were introduced in v2.3 and updated in v2.8 and v3. There is a great article from Justin Tadlock on custom taxonomies in v2.8 here and another from NetTuts on v3 custom taxonomies available here. If you’ve looked at the admin area of any decent theme you know that there are usually options to change the “type” of post (e.g. – aside, quote, gallery, etc.). Those defaults are all created in thecreate_initial_post_types()
function. v3 of WordPress added the ability to create custom post types. Here’s another great article from Justin Tadlock on custom post types in v3.
At this point most of the core, the Plugin API, taxonomies and post types are loaded so wp-settings
starts loading the active theme. It does this by executingregister_theme_directory()
and passing in get_theme_root()
as an argument. Both of these functions were defined in theme.php
. They are responsible for determining the location of and loading the active theme’s directory. Once the active theme’s directory has been loaded wp-settings
loads all active plugins by running aforeach()
loop to step through each plugin found by runningwp_get_active_and_valid_plugins()
. This function (defined in load.php
) looks through /wp-content/plugins
and returns any valid plugins that it finds. After the active plugins are loaded two new files are required. pluggable.php
and pluggable-deprecated.php
include useful functions for working with logged in users, sending mail and getting/setting user info. They are defined and required at this point so they can be overridden by any plugins loaded through the upcoming do_action( 'plugins_loaded' )
hook. The pluggable-deprecated.php
file is included to maintain backward compatibility but obviously none of those functions should be used because they will be removed in a future version. The default encoding is set next by running wp_set_internal_encoding()
which was defined in load.php
, it defaults to UTF-8. Now a quick check is made to see if the constant WP_CACHE
is set to true and if the wp_cache_postload()
function exists. If it does then it gets executed to setup any remaining caching related functionality that had to wait until more of the core was loaded. At this point the entire Plugin API is up and running so the do_action( 'plugins_loaded' )
hook is fired to enable plugin developers to execute any custom functionality provided in their plugins when they’re loaded.
wp-settings
now fires off wp_functionality_constants()
and wp_magic_quotes()
.wp_functionality_constants()
, defined in default-constants.php
, sets theAUTOSAVE_INTERVAL, EMPTY_TRASH_DAYS and WP_POST_REVISIONS
constants to handle the housekeeping for your posts. wp_magic_quotes()
, defined in load.php
, takes all the variables from $_GET, $_POST, $_COOKIE and $_SERVER
and sanitizes them by running stripslashes_deep()
and add_magic_quotes()
and then adds them to an array that gets assigned to $_REQUEST
. Then the do_action( 'sanitize_comment_cookies' )
hook is executed.
The next section of wp-settings
handles the creation and setup of some pretty important objects. First it creates a new WP_Query object and assigns it to the variable $wp_the_query
. Then it creates another variable that points to a reference to that variable called $wp_query
. This is the default loop that you’re accessing when you run if (have_posts()) : while (have_posts()) : the_post();
. After that’s done it creates the WP_Rewrite object (defined in rewrite.php
for handling permalinks) and assigns that to the global variables array in $GLOBALS['wp_rewrite']
. Then it creates a new WP object (which was defined in class-wp.php
and is responsible for creating the whole WordPress environment) and assigns it to the variable $wp
. Next it creates a new WP_Widget_Factory object and assigns that to the global variables array at $GLOBALS['wp_widget_factory']
, and finally creates a new WP_Roles object, assigning it to the global variables array at $GLOBALS['wp_roles']
Once all those tasks have competed the hook do_action( 'setup_theme' )
is executed to allow plugins to take action right as a theme is getting ready to be loaded.
Now wp-settings
moves on to setup a few environment requirements for getting our theme loaded. The function wp_templating_constants()
(defined in default-constants.php
) is executed at this point. This function is responsible for creating the constants familiar to theme designers, TEMPLATEPATH
and STYLESHEETPATH
. In addition, it checks to see if the WP_DEFAULT_THEME
constant has been set and if not it sets it to (currently) twentytwelve. This default theme is used for any new install of WordPress as well as if the current theme somehow goes missing. After that function theload_default_textdomain()
function is run to ensure that proper language settings are loaded. Once the default text domain has been set the default locale file is determined and required. Once both of those steps are complete a WP_Locale object is created and assigned to the global variables array at $GLOBALS['wp_locale']
. Anyone interested in how WordPress handles so many multiple languages or wants to help WordPress support more languages, these are the files you want to study.
We are so close to the end I can taste it! This next chunk of code will be interesting to any parent/child theme designer who wonders why a child’s functions.php
file is loaded before the parent’s, but all the parent’s template files are loaded before the child’s. I know I always have. After the locale is setup wp-settings
runs through an if statement checking the values of TEMPLATEPATH
and STYLESHEETPATH
. IfSTYLESHEETPATH
is different than TEMPLATEPATH
it loads it’s functions.php
first then it calls the one in TEMPLATEPATH
. I guess if you think it through it makes sense. You want the child to be able to set up any custom functions before the parent can define them. This is why parent themes should check if a function exists before executing it, just incase the child has defined a custom one. Once that code executes wp-settings
calls the do_action( 'after_setup_theme' )
hook for any themes or plugins that need to execute custom code when a theme is done with its setup. The init method of the $wp object is called next to setup the current user’s settings and the hookdo_action( 'init' )
is run. This is just about it folks, there is only one more check for MultiSite and then the hook do_action( 'wp_loaded' )
is run for any theme or plugin that needs to run any code once WordPress’ core has fully loaded. As the curtain sets on wp-settings
the WordPress core has completed loading and execution returns to wp-blog-header.php
. I know, it feels like we left that file a few days ago! It always amazes me that all of the functionality we just covered loads in mere seconds while the request is being processed.
If you’ve made it this far I would just like to congratulate you. We’re almost done! Lets just do a really quick recap of where we are at this point. When the visitor’s browser sent our server a request index.php
set WP_USE_THEMES
to true and required wp-blog-header.php
. That file first called wp-load.php
, then it executes the function wp()
and finally requires template-loader.php
. wp-load.php
defined the ABSPATH
constant and grabbed the site’s configuration settings from wp-config.php
before calling wp-settings.php
. wp-settings.php
(the majority of this article, which we just covered) handled the loading of all core functionality, plugins and the active theme. Now thatwp-settings.php
is complete and execution has returned to wp-blog-header.php
we can move on to the conclusion of our tour through WordPress’ initialization.
wp-blog-header.php
now executes a function defined in functions.php
named wp()
. If you weren’t paying attention, about 3/4 of the way through wp-settings.php
a global variable named $wp
was defined and instantiated as a WP object (that WP object was defined in class-wp.php
). This object is responsible for controlling the entire WordPress environment after it’s been loaded. The wp()
function called by wp-blog-header.php
finalizes the setup of this object by calling its main()
function. This effectively puts the finishing touches on the global WordPress environment and also ensures that the current query has been properly configured so The Loop works the way we all expect it to. I gotta give one final shout-out to Mark Jaquith for pointing me to the info on this function. I’m tellin’ you this guy is a badass! If you don’t follow him on Twitter, do yourself a favor and follow him now. I’ll just say this, that thing on his shoulders ain’t just a hat rack my friends!
We can now finally display a page to our visitor! The template-loader.php
file is responsible for determining not only what template should be used for displaying the content but also what kind of visitor our server is responding to. If this request is for a robot, a feed or a trackback then it serves the appropriate content for those requests. If the current request is from a robot then it calls the do_robots
hook. This hook is defined in functions.php
and serves a robots.txt file when called. If the request is for one of our feeds then the function do_feed()
is called (also defined in functions.php
) and then serves whichever feed format has been requested. If the request is a trackback or pingback then the wp-trackback.php
file is required. This file runs through some fancy checks and then builds the response which is served back based on whether a trackback or pingback request was received. If the request is for anything other than what we just covered then WordPress steps through a 25 line elseif statement to determine the type of template to load. This is how the Template Hierarchy is implemented in WordPress. There’s a great overview of the template hierarchy, written by Chris Coyier, over at his (and Jeff Star’s) Digging into WordPresssite. I highly recommend that site in general, loads of great tips and tricks!
WHEW!! Well, if you think about it, everything we just covered is what happened when you clicked whatever link brought you to this post. It’s taken me a lot longer than I expected to write this; my back hurts and I really need to get back to learning some Ruby programming! So I’m just going to thank you if you’ve made it to the end. Thank you for sticking with me. I hope you’ve learned as much reading this as I did writing it. I intend to be back soon with a (shorter) post on a more specific topic.
我有时间的时候,翻译一下。
我最初学习Wordpress一方面是通过自己做一些主题,另一方面是在网上阅读一些优秀的教程.在反复的练习和错误中我学习了很多,在只是粘贴和复制中我也学习了很多.但是我还没有遇到一个全面讨论关于Wordpress如何初始化的话题.初始化的概念就是:Wordpress收到最初的客户请求后如何把一个漂亮的网页呈现在用户面前?现在是时候花大量精力去一个文件一个文件的去了解Wordpress了.这样也便于我了解这个我最喜爱的内容发布平台是如何完成自己的初始化的过程,是如何把那些精彩的内容呈现在用户面前.我希望这篇文章一方面自己可做为备份,另一方面也希望想更清晰的了解Wordpress的工作原理和组织架构的你提供参考,我想这对于一个刚刚学会Wordpress,但又想很清楚Wordpress的工作机制的人来说还是会有一些帮助的.言归正传,我们开始吧.
这篇文章是基于Wordpress的主干核心文件(函数).所有的编译文件都是指向该文件的主干核心文件.我这样做的原因是Wordpress更新的速度比我这篇文章更新的速度要快.所以,不管我写的这篇文章的内容是否更新,下面的一些链接会把Wordpress最新的相关文件呈现在你的面前.所以说,下面的一些链接也不一定是你目前在用的Wordpress版本的文件.如果你需要参考Wordpress以前的版本的核心代码的话,这篇文章也是挺接近的.
更新:在2013年1月29号的时候,我检查了这些链接和内容,并把相关信息更新至目前使用的最新版本:V3.5.1.
Index.php是所有文件的入口(是魔术的开始).Wordpress每显示一个页面,index.php都会处理初始请求.index.php主要完成两个任务.首先,他定义了一个常量叫’WP_USE_THEMES’ 并把这个常量设置为true.这是告诉Wordpress应该使用激活的那个主题显示内容,然后呢,这个index.php引入了wp-blog-header.php这个文件.index.php和wp-blog-header.php都位于wordpress的根目录下.
在Wordpress的初始化过程中wp-blog-header.php这个文件主要完成三个重要的工作.首先,
wp-blog-header.php引入了wp-load.php这个文件,然后执行wp()函数,最后引入template-loader.php文件. wp-load.php也是位于Wordpress的根目录下.wp()函数是在/wp-includes/functions.php这个文件里面定义的,template-loader.php和functions.php文件都是位于/wp-includes目录下.
我们首先来看一下wp-load.php这个文件以及其引用文件. wp-load.php内容很简单,但是在Wordpress的初始化的过程中起着相当重要的作用.这个文件首先定义了’ABSPATH’常量,这个常量是Wordpress的根目录,在Wordpress初始化的进程中,这个常量会极其广泛使用,并且因着这个常量,Wordpress会很方便的调用位于Wordpress根目录下的配置文件和其他文件. wp-load.php引入wp-config.php文件后,他自身的工作就算是完成了,想必大家对wp-config.php文件会很熟悉,在很早的时候安装Wordpress的过程中可能需要手动编辑该文件,现在是省事不少,Wordpress可以自成生成该文件,并且配置好.事实上,wp-load.php文件会检查wp-config.php文件的位置,绝大部分程序员都会把wp-config.php文件放在Wordpress安装的根目录下,但是可能是处于安全的缘故,有些程序员会把wp-config.php文件放在其他的地方(在路径设置正确的情况下,这种情况是允许的),但如果wp-load.php文件找不到wp-config.php的话,wp-load.php文件会生成一个很友好的错误提示,并且有一个生成wp-config.php文件的按钮.
接着Wordpress就开始有一系列的动作了.
如果wp-load.php成功的加载了wp-config.php文件的话,在他处理加载Wordpress核心文件之前,会根据wp-fonig.php文件里的设置来做相应的配置.wp-config.php文件的注释部分有非常好的说明”该文件有以下的相关配置:MySQL的设置,数据库表的前缀,安全码,Wordpress的语言,和ABSPATH.这个文件的注释部分说的很好,我就不作过多的说明.wp-config文件解析完毕后,Wordpress就获取到所需的各种信息,然后连接数据库,接着是加载内容.我不知道为什么这里再一次的检查了ABSPATH文件,wp-config的最后一行是引入了wp-setting.php文件,Wordpress的绝大部分文件都是wp-setting.php文件引入的.
wp-setting.php一开始就定义了一个’WPINC’常量,这个常量是指向/wp-inludes 文件夹(上面有提到过).Wordpress初始化的大部分预定义函数(或作方法,这里出现的function统一翻译成函数).通过定义该常量,接着wp-setting.php很方便的从 /wp-includes 文件夹里引入了load.php,default-constants.php和version.php这三个文件.事实上,此时Wordpress并没有立即执行这些函数,只是用了php的 require()语句去引入包涵这些函数的文件,以备不时之需. load.php(位于 /wp-include.php文件里面)文件里面定义了以下函数.
这个函数首先判断register_globals是不是打开了,那么这个是什么用途呢,如果这个变量打开了,则会产生如下效果,可以从url中获取变量值,例如$_GET["var"] = “abc”; 那么打开以后默认$var = “abc”; (可以参考官方文档)
修改$_SERVER 变量.
检查php和mysql的版本信息
这个文件是当用户输入 ..wordpress/favicon.ico的时候就不必加载Wordpress.
PHP4 中标准的系统时间捕获方式
返回时间,并且当 $display = 1 时输出时间
设置PHP的错误处理方式和 WP 的调试模式。
设置常量 WP_LANG_DIR,即语言文件所在的文件夹。
加载和数据库有关的Class.
设置数据库表前缀和数据库表列的格式说明符。
开启对象缓存。如果wp-content文件夹中存在object-cache.php文件,则使用他作为扩展的对象缓存。
如果还没有安装 WP,则启动安装程序
返回 must-use 插件的文件数组,默认的 must-use 插件在 wp-content/mu-plugins 目录,如果要修改默认目录,可配置 wp-config.php 文件中的 WPMU_PLUGIN_DIR 和 WPMU_PLUGIN_URL 常量。
wp_get_active_and_valid_plugins()
返回激活的合法的插件文件数组,默认的插件在 wp-content/plugins 目录,如果要修改默认目录,可配置 wp-config.php 文件中的 WP_PLUGIN_DIR 和 WP_PLUGIN_URL 常量。
利用 mb_internal_encoding() 函数设置内部编码方式,默认设置为UTF-8.
对 $_GET, $_POST, $_COOKIE, and $_SERVER 添加魔术引用
触发挂载点 do_action( ‘shutdown’ ),在PHP关闭执行之前运行。
克隆对象。只有在 PHP5 以上的版本中才能克隆成功,否则返回原来的对象。
返回当前请求是否在 WP 的后台。
返回当前请求是否在 WP 的管理面板中(network administration).
Checks whether the current request is for a network admin screen /wp-admin/network/
Checks whether the current request is for a user admin screen /wp-admin/user/
返回是否支持多站点
返回当前Blog的id
这里是检查加载异常,是否有些文件被重复加载,如果有,则中止程序.
一旦以上的几个必需函数加载成功后,wp-setting.php引入了 default-constants.php文件,这个文件里面定义了6个函数.这些函数主要是定义了一些Wordpress在接下来的初始化进程中需要用到的常量(这些变量通常wp-config.php中改写).
1)wp_initial_constants( ),定义 WP 初始化常量 WP_MEMORY_LIMIT,WP_CONTENT_DIR,WP_DEBUG,WP_DEBUG_DISPLAY,WP_DEBUG_LOG,WP_CACHE,MEDIA_TRASH,SHORTINIT 和全局变量 $blog_id(用于设置多博客)。
2)wp_plugin_directory_constants( ),定义 WP 插件文件夹的常量 WP_CONTENT_URL,WP_PLUGIN_DIR,WP_PLUGIN_URL,WPMU_PLUGIN_DIR,WPMU_PLUGIN_URL。
3)wp_cookie_constants( ),定义 WP 与cookie相关的常量 COOKIEHASH,USER_COOKIE,PASS_COOKIE,AUTH_COOKIE,SECURE_AUTH_COOKIE,LOGGED_IN_COOKIE,TEST_COOKIE,COOKIEPATH,SITECOOKIEPATH,ADMIN_COOKIE_PATH,PLUGINS_COOKIE_PATH,COOKIE_DOMAIN。
4)wp_ssl_constants( ),定义 WP 与 ssl 相关的常量 FORCE_SSL_ADMIN,FORCE_SSL_LOGIN。
5)wp_functionality_constants( ),定义 WP 与功能相关的常量 AUTOSAVE_INTERVAL,EMPTY_TRASH_DAYS,WP_POST_REVISIONS。
6)wp_templating_constants( ),定义 WP 与模板相关的常量 TEMPLATEPATH,STYLESHEETPATH,WP_DEFAULT_THEME。
接着wp-setting.php加载了version.php文件.wp-setting.php定义了以下6个变量.
$wp_version
Wordpress的版本信息
$wp_db_version
Wordpress数据库版本信息
$tinymce_version
Wordpress编辑器(我的最爱^^)版本信息.
$manifest_version
Wordpress缓存机制相关的版本信息
$required_php_version
Wordpress所需的PHP版本信息(安装需求)
$required_mysql_version
Wordpress所需mySQL版本信息. (安装需求)
(未完待续... ...)
果断收藏