WordPress工作原理之程序文件执行顺序
在了解WordPress挂载机制时,一直有一个疑惑,到底是WordPress的内核源文件先执行还是主题文件里functions.php文件先执行。为了解决这个问题,想了解WordPress的工作原理,它是如何生成网页的,各程序文件的执行顺序是什么,于是有了这篇文章。
WordPress所有的前端页面生成都要经过根目录下的index.php文件(不是主题根目录),这是通过Web服务器的rewrite规则实现的。然后通过index.php文件一步步引导WordPress环境启动,再分析请求URL返回相应数据所组成的前台页面。以下将一步步分析源码文件,以此来了解WordPress整体框架及工作原理。
第一步:加载index.php文件
该文件有效源码如下:
define('WP_USE_THEMES', true);
//定义是否加载主题文件,true为加载;
require('./wp-blog-header.php');
//加载wp-blog-header.php文件,该文件用于启动WordPress环境及模板;
第二步:加载wp-blog-header.php文件
该文件有效源码如下:
if ( !isset($wp_did_header) ) {
# 判断$wp_did_header变量是否已经设置,如果未设置则执行代码块;
$wp_did_header = true;
# 见解析1;
require_once( dirname(__FILE__) . '/wp-load.php' );
# 见解析2;
wp();
# 见解析3;
require_once( ABSPATH . WPINC . '/template-loader.php' );
# 见解析4;
}
解析1: 对$wp_did_header进行赋值,这样如果代码块已经执行过,判断就会失败,代码块就不会再执行。这种做法可以确保wp-blog-header.php文件只执行一次(重复执行的话会出现函数名冲突、变量重置等,WordPress会精神分裂的!);
解析2: 加载WP根目录下wp-load.php文件,执行初始化工作,如初始化常量、环境、加载类库和核心代码等完成WordPress环境启动工作,如加载wp-includes目录下functions.php(函数库)、class-wp.php(类库)、plugin.php(插件)、pomo目录(语言包)、query.php(数据请求)、theme.php(加载主题文件)、post-template.php(文章模板)、comment.php(评论模板)、rewrite.php(URL重写)等等。
解析3: 执行wp()函数,执行内容处理工作,如根据用户的请求调用相关函数获取和处理数据,为前端展示准备数据;
解析4: 加载根目录绝对路径下wp-includes目录中template-loader.php文件,执行主题应用工作,如根据用户的请求加载主题模板。
WordPress之所以能将用户请求的页面生成出来,都是最后这三行核心代码起的作用。
wp-load.php会完成页面生成所需要的所有环境、变量、API等,相当于做了好准备工作;wp()函数根据用户请求的URL从数据库中取出相应的数据内容备用;
template-loader.php把已经准备好的内容用主题所设定的样式展现方式给拼接出来。这三项工作完成,就可以将用户请求的页面展现出来了。
我们姑且将这三项工作也认定为三个大步骤,以下将重点分析。
第三步:加载wp-load.php文件(初始化)
该文件初始化常量(如:定义绝对路径、设定功能文件及内容文件路径等)并加载wp-config.php文件(本处不分析wp-config.php文件不存在的情况),部分核心代码如下:
define( 'ABSPATH', dirname(__FILE__) . '/' );
# 定义常量ABSPATH为根目录绝对地址;
require_once( ABSPATH . 'wp-config.php' );
# 加载根目录下wp-config.php文件;
从代码看出,本文件的主要作用就是加载wp-config.php文件,故我们可以抽象的将之看作是wp-load.php初始化时的第一个小步骤,具体如下:
1. 加载wp-config.php文件
该文件主要用于配置MySQL数据库通信信息、设定数据库表名前缀、设定密钥、设置语言及文件绝对路径等,部分核心代码如下(为省事就直接在代码后加#然后解释含义了):
define('DB_NAME', 'db_name');
# 定义数据库名db_name;
define('DB_USER', 'db_username');
# 定义数据库用户名db_username;
define('DB_PASSWORD', 'db_password');
# 定义数据库密码db_password;
define('DB_HOST', 'db_host_location');
# 定义数据库主机地址,如localhost或其他IP;
define('DB_CHARSET', 'utf8');
# 定义数据表默认文字编码,如utf8;
$table_prefix = 'wp_';
# 定义数据库表前缀,一般默认为wp_;
define('WPLANG', 'zh_CN');
# 定义WordPress语言,中文默认zh_CH,使用的汉化语言文件为/wp-content/languages目录下的zh_CH.mo文件,该文件为二进制,查看具体中文可见zh_CH.po文件;
define('WP_DEBUG', false);
# 设置开发环境DEBUG,默认为false不开启;
require_once(ABSPATH . 'wp-settings.php');
# 加载根目录下wp-settings.php文件;
代码中定义的数据库常量主要用于数据请求时通信数据库,本文件还有个主要作用就是加载了wp-settings.php文件,而该文件相当于启动WordPress环境的总指挥,下面我们就将该文件作为初始化的第二步来分析。
2. 加载wp-settings.php文件
该文件主要用于创建和定义常见变量、函数和类的库来为WordPress运行做准备,也就是说WordPress运行过程中使用的大多数变量、函数和类等核心代码都是在这个文件中定义的。这个文件相当于一个总控制器,很多常量定义、函数定义等都是在其他文件中完成,而该文件的作用就是执行那些文件或执行在那些文件中已经定义好的函数。
该文件源码分析内容较多,详见"WordPress核心文件wp-setting.php源码分析”。
第四步: 执行wp()函数(内容处理)
在这一阶段,调用wp()函数对数据库内容进行查询,并将查询的内容赋值给一些全局变量,方便在模板中使用模板标签获取相应的数据并展示在前端。该函数源码如下:
function wp( $query_vars = '' ) {
global $wp, $wp_query, $wp_the_query;
# 对变量$wp,$wp_query,$wp_the_query进行全局化;
$wp->main( $query_vars );
# 见解析1;
if ( !isset($wp_the_query) )
$wp_the_query = $wp_query;
# 见解析2;
}
解析1:调用$wp->main(),即调用对象$wp的main()方法,该对象是class-wp.php文件中WP类实例化得到的,该类主要用于启动WordPress环境,main()方法源码分析详见“WordPress核心类WP内main()方法源码分析”;
解析2:判断$wp_the_query是否设置,若未设置将其赋值为$wp_query,该对象是query.php文件中WP_Query类实例化得到的,该类作用强大,几乎WP所需要的所有数据信息都是由该类得到的,所以内容的准备工作基本都是这段代码来完成的,该类的具体分析见“”;
至此,WP根据请求准备相应数据的工作也已经完成,下面就需要加载模板并把这些数据展现到前台去了。
第五步:加载template-loader.php文件(主题应用)
该文件根据用户URL返回加载相应模板,其源码如下:
if ( defined('WP_USE_THEMES') && WP_USE_THEMES )
do_action('template_redirect');
# 如果常量WP_USE_THEMES存在且值为真,则触发挂载点(动作钩子)template_redirect;
if ( is_robots() ) :
do_action('do_robots');
return;
elseif ( is_feed() ) :
do_feed();
return;
elseif ( is_trackback() ) :
include( ABSPATH . 'wp-trackback.php' );
return;
endif;
# 判断函数is_robots(), is_feed() 和 is_trackback()的返回结果,处理 feeds 和 trackbacks,即使没有使用任何主题;
if ( defined('WP_USE_THEMES') && WP_USE_THEMES ) :
$template = false;
if ( is_404() && $template = get_404_template() ) :
elseif ( is_search() && $template = get_search_template() ) :
elseif ( is_tax() && $template = get_taxonomy_template() ) :
elseif ( is_front_page() && $template = get_front_page_template() ) :
elseif ( is_home() && $template = get_home_template() ) :
elseif ( is_attachment() && $template = get_attachment_template() ) :
remove_filter('the_content', 'prepend_attachment');
elseif ( is_single() && $template = get_single_template() ) :
elseif ( is_page() && $template = get_page_template() ) :
elseif ( is_category() && $template = get_category_template() ) :
elseif ( is_tag() && $template = get_tag_template() ) :
elseif ( is_author() && $template = get_author_template() ) :
elseif ( is_date() && $template = get_date_template() ) :
elseif ( is_archive() && $template = get_archive_template() ) :
elseif ( is_comments_popup() && $template = get_comments_popup_template() ) :
elseif ( is_paged() && $template = get_paged_template() ) :
else :
$template = get_index_template();
endif;
# 见解析1;
if ( $template = apply_filters( 'template_include', $template ) )
include( $template );
return;
endif;
# 若template_include过滤钩子上有挂载函数,则对$template进行应用,最终将内容呈现给用户;
解析1:如果常量WP_USE_THEMES存在且值为真,则判断页面类型同时给$template变量赋相应值;其中,判断页面类型的函数如is_404()位于wp-includes目录下query.php文件,该函数返回对象$wp_query中is_404()方法,若is_404()为false则继续往下判断是否是其他页面;若为true则给$template赋值为get_404_template(),该函数位于wp-includes目录下template.php文件,它返回get_query_template('404'),而该函数将页面类型传入数组$templates并应用调用函数locate_template($templates)且应用过滤器;locate_template()函数根据传入数组在主题中查找到相应的文件然后交给load_template()函数然后使用require加载,最终将用户需要的页面呈现出来;
WordPress工作原理之程序文件执行顺序的更多相关文章
- 【总结】/etc/rc.d/rc.local 与 /etc/profile .bash_profile .bashrc 文件执行顺序
登陆shell与交互式非登陆shell的区别 登录shell 所谓登录shell,指的是当用户登录系统时所取的那个 shell.登录shell属于交互式shell. 登录shell将查找4个不同的启动 ...
- JavaScript程序的执行顺序
JavaScript程序的执行顺序:同步==>异步==>回调 同步是阻塞模式,异步是非阻塞模式. 同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个 ...
- iOS程序的执行顺序 和 UIViewController的生命周期
iOS程序的执行顺序 1 进入程序的入口 进入main函数, 设置AppDelegate称为函数的代理 2 程序完成加载 -[AppDelegate application:didFinishLau ...
- Java文件执行顺序总结
类执行顺序 一个java文件的执行过程: 编译:加载的类,加载的时候对类中的资源进行编译,首先是静态成员变量,静态方法等,如果有相应操作,就会进行相应的操作, 并且这个Static修饰后的静态成员变量 ...
- wordpress工作原理
WP初始化的过程:当你输入<yourlink>/wordpress对wordpress进行初始化时,wordpress默认会找根目录下的index.php页面,看一下index.php页面 ...
- 黄聪:wordpress工作原理
WP初始化的过程:当你输入<yourlink>/wordpress对wordpress进行初始化时,wordpress默认会找根目录下的index.php页面,看一下index.php页面 ...
- day03_05 Python程序文件执行和与其他编程语言对比
python在windows操作系统上是没有的,但是在linux上默认就有python 执行python程序的方式有两种: 1.交互器,缺点 程序不能永久保存,主要用于简单的语法测试 2.文件执行 对 ...
- Struts2工作原理和核心文件
一.Struts2工作原理 如下图: 二.Struts2配置文件 1.web.xml 任何MVC框架都需要与Web应用整合,这就不得不借助于web.xml文件,只有配置了web.xml文件的Servl ...
- 关于js预编译以及js文件执行顺序的几个问题。
关于js的执行原理,除去html页面中直接添加的代码,js代码的放置可以分为两类. //情形a <script type="text/javascript" ...
随机推荐
- kindEditort图片自动上传
参考:http://www.cnblogs.com/jaxu/p/3824583.html (赞一个)
- Java Hour 41 Maven ( 3 )
有句名言,叫做10000小时成为某一个领域的专家.姑且不辩论这句话是否正确,让我们到达10000小时的时候再回头来看吧. 41.1 m2eclipse 简介 m2eclipse 是一款开源工具,为ec ...
- SQL DEVELOPER工具找不到database时的解决
1.配置SQL DEVELOPER管理工具 这里省略Oracle数据库和PL/SQL Developer的安装步骤,注意在安装PL/SQL Developer软件时,不要安装在Program File ...
- InputStream的三个read的区别
转自:http://www.blogjava.net/toby/archive/2009/04/24/267413.html 1.read这个方法是对这个流一个一个字节的读,返回的int就是这个字节的 ...
- SQL Server:分离和重新附加数据库
对于分离一个数据库来说,我们可以用Manage Studio界面或者存储过程.但是对于每一种方法都必须保证没有用户使用这个数据库.接下来所讲的都是对于用命令来分离或附加一个数据库.对于用Manage ...
- 打开别人Xamarin项目找不到android.jar文件
打开别人Xamarin项目找不到android.jar文件 错误信息:Could not find android.jar for API Level 23.打开非本机创建的Xamarin项目,编译的 ...
- 简单几何(求划分区域) LA 3263 That Nice Euler Circuit
题目传送门 题意:一笔画,问该图形将平面分成多少个区域 分析:训练指南P260,欧拉定理:平面图定点数V,边数E,面数F,则V + F - E = 2.那么找出新增的点和边就可以了.用到了判断线段相 ...
- 递推DP URAL 1081 Binary Lexicographic Sequence
题目传送门 题意:问第k个长度为n的01串是什么(不能有相邻的1) 分析:dp[i][0/1] 表示前i个,当前第i个放1或0的方案数,先预处理计算,dp[i][1]只能有dp[i-1][0]转移过来 ...
- ZOJ3228 Searching the String(AC自动机)
题目大概是给一个主串,询问若干个模式串出现次数,其中有些模式串要求不能重叠. 对于可以重叠的就是一个直白的多模式匹配问题:而不可重叠,在匹配过程中贪心地记录当前匹配的主串位置,然后每当出现一个新匹配根 ...
- HDU2167 Pebbles(状压DP)
题目给一张n×n的格子,每个格子都有数字,要从格子中取若干个数字,八个方向相邻的数字不能一起取,问取的数字最大和是多少. 从第一行一行一行看下去,可以发现第1行取哪几列只会影响到第2行,第3行后面的一 ...