WP笔记

WordPress Actions加载顺序

写WordPress代码时需要不停的与hooks(actions and filters)打交道,filter就像茶壶的过滤嘴,茶壶在哪它就在哪,顺序问题不那么重要。而action是一种行为,比如掀起壶盖和盖上壶盖之间就可以放一个action,在这个action里可以放茶叶,不掀起壶盖是不可以放茶叶的,所以actions加载顺序很重要。

WordPress中的actions

actions可以理解为一组在系统加载到某一时刻要执行的functions集合,使用do_action()添加,例如我们经常用到的get_header()函数,是这样定义的

function get_header( $name = null ) {
	do_action( 'get_header', $name );

	$templates = array();
	if ( isset($name) )
		$templates[] = "header-{$name}.php";

	$templates[] = 'header.php';

	// Backward compat code will be removed in a future release
	if ('' == locate_template($templates, true))
		load_template( ABSPATH . WPINC . '/theme-compat/header.php');
}

函数第二行用do_action()注册了一个action,叫做get_header

do_action( 'get_header', $name );

如果我们在functions.php中或者插件中写

add_action('get_header','my_fun')

my_fun()这个函数就会在do_action的位置执行,而不是在functions.php运行的位置执行。

Actions加载顺序

了解WordPress中actions的执行顺序,可以知晓在这个action执行时,是否已经具备某些资源,例如登陆用户信心、例如插件API等。

要了解Actions的执行顺序,可以安装一个开发人员的插件WordPress Hook Sniffer,该插件不仅能告知actions的加载顺序,还能知道当前页面add_action操作有哪些,remove_action操作有哪些,还有filters信息。

用这个插件查看了安装默认主题时action的执行顺序,捡了一些重要的记录下来,红色字体标记了一下比较重要的阶段。

muplugins_loaded (最先加载的action)

registered_taxonomy

registered_post_type

(加载所有激活的插件的文件,这是插件代码被执行的位置)

plugins_loaded

sanitize_comment_cookies

setup_theme

(载入当前主题的functions.php,functions.php中没有用add_filter或add_action添加的函数在这里被执行)

after_setup_theme (这个钩子看着眼熟吧,默认主题开头就有)

auth_cookie_malformed

auth_cookie_valid

set_current_user (这里执行了wp_set_current_user()函数,全局变量$current_user产生)

init

widgets_init

register_sidebar

wp_register_sidebar_widget

wp_default_scripts

wp_default_styles

admin_bar_init

add_admin_bar_menus

wp_loaded

parse_request

send_headers

parse_query

pre_get_posts

posts_selection

wp

template_redirect

加载激活的主题的模板(例如index.php、page.php等)

get_header

wp_head

wp_enqueue_scripts

wp_print_styles

wp_print_scripts

wp_print_scripts

get_footer

wp_footer

从上面的列表中可以看出一些问题:

  • 插件文件比主题的functions.php加载更早
  • 插件加载时,wp_set_current_user()尚未执行,因此在插件文件的body中无法直接获取用户信息
  • init和after_setup_theme的区别是,后者执行时尚未调用wp_set_current_user(),没有授权用户信息
  • 加载主题模板文件发生在最后阶段,此阶段中不管是插件的代码还是functions.php中的代码都已执行,这样我们就不奇怪为什么在single.php中调用query_posts()会增加查询次数,query_posts()大约在pre_get_posts的位置就执行完了,等程序执行到single.php时,如果调用query_posts,只能推翻前面的结果重新查一遍。我们还能看出,避免这个问题的方法就是在functions.php中使用filters函数(posts_join, posts_groupby等)更改query_posts的查询参数,因为functions.php早于query_posts执行,方法可以参考《自定义WordPress查询的4种方法》中的第三种方法。

理解万岁

与其枯燥的去记忆什么时候该用哪个action,不如理解一下WordPress的启动过程,了解actions加载的顺序,记忆几个比较重要的过程,例如哪些actions发生在插件代码执行以后,哪些actions发生在functions.php加载以后。

3条评论

  1. Pingback: WordPress:如何判断登录用户的角色 | ~SolagirL~
  2. Pingback: 关于条件标签的使用位置 | ~SolagirL~
  3. Pingback: 为什么WordPress插件下有很多目录 | ~SolagirL~

评论已关闭。