源码可以直接下载WordPress的安装包后解压得到,或者把已经安装好的WordPress站点的下的文件拷贝出来。
这里走读的源码是WordPress4.7版本,安装完成后的,站点目录下的源码文件。
首先准备一个好用的IDE,方便阅读代码过程中,查看变量、函数定义等,这里用的是phpstorm。
打开phpstorm的时候,在项目列表提示界面,
选择"Create New Project from Existing Files",根据提示将Project Root设置我们下载的源码的目录。
完成后,就可以在IDE的左侧看到源码文件列表。
个人习惯了Vim的快捷键,所以走读代码前,先给phpstorm安装了一个vim插件:
在"file->setting->Plugins"中搜索vim,找到IdeaVim后安装。
安装完成后重启phpstorm。
index.php引入wp-blog-header.php
require( dirname( __FILE__ ) . '/wp-blog-header.php' );
wp-blog-header.php引入wp-load.php之后,就开始接收查询:
require_once( dirname(__FILE__) . '/wp-load.php' );
// Set up the WordPress query.
wp();
在wp-includes/functions.php中可以找到wp()的实现,可以看到直接使用全局变量wp的main方法:
function wp( $query_vars = '' ) {
global $wp, $wp_query, $wp_the_query;
$wp->main( $query_vars );
if ( !isset($wp_the_query) )
$wp_the_query = $wp_query;
}
在phpstorm中利用跳转功能没有找到$wp的定义,所以我们从wp-load.php中按顺序走读代码,看看在wp()执行之前,都发生了写什么。
从wp-load.php的代码可以看到,wp-load.php最终的工作其实就是加载wp-config.php
从wp-config.php的代码可以看到,wp-config.php的最终的工作就是加载wp-settings.php:
wp-settings.php的完成的工作较多
定义WPINC为wp-include,下面加载的文件基本都是位于wp-include目录下的。
加载load.php:
load.php中全都是函数的定义和实现
加载default-constants.php:
default-constants.php中也全都是函数的定义和实现
加载plugin.php:
plugin.php中定义了并初始化了三个全局变量: $wp_filter, $wp_actions, $wp_current_filter
定义全局变量:
$wp_version, $wp_db_version, $tinymce_version, $required_php_version,
$required_mysql_version, $wp_local_package
加载version.php:
version.php定义了版本相关的变量
继续走读wp-settings.php,可以看到wp-settings.php中继续加载了一堆的php文件,最后终于看到了想要的global变量的定义:
$GLOBALS['table_prefix'] = $table_prefix;
$GLOBALS['wp_embed'] = new WP_Embed();
$GLOBALS['wp_plugin_paths'] = array();
$GLOBALS['wp_the_query'] = new WP_Query();
$GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];
$GLOBALS['wp_rewrite'] = new WP_Rewrite();
$GLOBALS['wp'] = new WP(); <-- 我们要找的$wp的定义
$GLOBALS['wp_widget_factory'] = new WP_Widget_Factory();
$GLOBALS['wp_roles'] = new WP_Roles();
$GLOBALS['wp_locale'] = new WP_Locale();
$GLOBALS['wp_locale_switcher'] = new WP_Locale_Switcher();
$GLOBALS['wp_locale_switcher']->init();
如果wordpress是一个代码风格良好,结构清晰的项目,那么上面的这些全局变量应该就是所有重要的全局变量了。
另外 wp-settings.php中还做了很多其它的工作,为了主线清晰,这里暂时不深究。
在上面”wp-blog-header.php的工作”的章节中,看到wp-blog-header调用了函数wp()。
而wp()是从index.php走读下来,遇到的第一个处理外部请求的函数,在wp-includes/functions.php中实现:
function wp( $query_vars = '' ) {
global $wp, $wp_query, $wp_the_query;
$wp->main( $query_vars );
if ( !isset($wp_the_query) )
$wp_the_query = $wp_query;
}
从上面的实现可以看到,处理工作都是在$wp->main中完成的,因此推断,Class WP是统筹整个Wordpress的类,它统一接收所有的请求,并为不同的请求选择不同的处理方法(也就是路径路由)。所以核心就是WP类的实现。
WP类在wp-includes/class-wp.php中实现,是一个700行代码的,庞大的类。在它的main方法中,可以看到繁琐的uri处理过程。细节全在源码中,这里不做展开。
登录的时候,访问的名为wp-login.php的页面,例如
http://XXX.XXX.XXX/wp-login.php
所以直接去看文件wp-login.php中实现。
首先加载了wp-load.php:
require( dirname(__FILE__) . '/wp-load.php' );
可以推断出,只要加载了wp-load.php,就可以使用wordpress的核心功能。
然后判断登录过程是否要强制使用https:
if ( force_ssl_admin() && ! is_ssl() ) {
if ( 0 === strpos($_SERVER['REQUEST_URI'], 'http') ) {
wp_redirect( set_url_scheme( $_SERVER['REQUEST_URI'], 'https' ) );
exit();
} else {
wp_redirect( 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
exit();
}
}
又是一堆函数定义,先不管它们,先找到主线。在一堆函数定义过后,终于找到了主线。
Oh..My God! 业务逻辑和html页面杂糅在一起,GET/POST杂糅的方法,sorry,接受不了… 。
Goodbye~~