WordPress4.7源码走读

下载WordPress源码

源码可以直接下载WordPress的安装包后解压得到,或者把已经安装好的WordPress站点的下的文件拷贝出来。

这里走读的源码是WordPress4.7版本,安装完成后的,站点目录下的源码文件。

IDE

首先准备一个好用的IDE,方便阅读代码过程中,查看变量、函数定义等,这里用的是phpstorm

打开phpstorm的时候,在项目列表提示界面,

选择"Create New Project from Existing Files",根据提示将Project Root设置我们下载的源码的目录。

完成后,就可以在IDE的左侧看到源码文件列表。

个人习惯了Vim的快捷键,所以走读代码前,先给phpstorm安装了一个vim插件:

在"file->setting->Plugins"中搜索vim,找到IdeaVim后安装。

安装完成后重启phpstorm。

从index.php开始

index.php引入wp-blog-header.php

require( dirname( __FILE__ ) . '/wp-blog-header.php' );

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-load.php最终的工作其实就是加载wp-config.php

wp-config.php的工作

从wp-config.php的代码可以看到,wp-config.php的最终的工作就是加载wp-settings.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中还做了很多其它的工作,为了主线清晰,这里暂时不深究。

Class WP

在上面”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~~

作者微信

推荐阅读

Copyright @2011-2019 All rights reserved. 转载请添加原文连接,合作请加微信lijiaocn或者发送邮件: [email protected],备注网站合作

友情链接:  李佶澳的博客  小鸟笔记  软件手册  编程手册  运营手册  爱马影视  网络课程  奇技淫巧  课程文档  精选文章  发现知识星球  百度搜索 谷歌搜索