WordPress 插件执行过程原理分析

发布于 2017-12-17 10:07:18 字数 6692 浏览 3551 评论 0

WordPress 的插件机制使得开发者可以方便地向系统添加自己需要的功能,而这是使得 Wordpress 得以在全世界流行的重要原因。

WordPress 插件执行过程原理分析

一个 WordPress 插件是一个程序,或者是用 PHP 脚本语言写出的一个或一些函数的集合,用来往 WordPress 博客里增加一些特定的特征和服务,它们可以通过 WordPress 的插件 API 提供的接入点和函数无缝的集成到 WordPress 中。

插件机制的实现主要依靠 wp-includes 目录下的 plugin.php 文件,该文件中包含了与插件机制相关的几个函数。在 WordPress 内核运行时设立了一些标记(tag),当遇到这些标记时,WordPess 会自动调用挂载到(hook to)这个标记上的所有函数,该功能是通过数组来实现的。

插件 HOOK 原理

用户可以通过 plugin API 方便的将自定义的功能添加到系统相应的位置。需要指出的是 WordPress 定义了两种类型的插件 API,行为(Actions)和过滤器 (Filters):

Actions: Actions are the hooks that the WordPress core launches at specific points during execution, or when specific events occur. Your plugin can specify that one or more of its PHP functions are executed at these points, using the Action API.

Actions 是由 WordPress 内核在执行过程中的特定的点或者特定的事件发生时调用的,使用这些 Action API,你的 plugin 可以指定在这些点去执行一个或者多个 PHP 函数.

Filters: Filters are the hooks that WordPress launches to modify text of various types before adding it to the database or sending it to the browser screen. Your plugin can specify that one or more of its PHP functions is executed to modify specific types of text at these times, using the Filter API.

Filters 是一种 hooks,由 WordPress 调用,针对于各种形式的文本,让它们在进入数据或发送到浏览器之前得到调整。使用 Filter API,你的插件可以指定在某个时间执行一个或者多个PHP函数来修改特定类型的文本。

插件的开发过程

下面弄的一个 simple_song 插件(其实跟自带的那个插件是一样的只是修改了歌词而已)为例简述整个过程三个步骤:编写插件要执行的代码,添加 add_action(),进入后台激活它。

该插件的功能是:在 WordPress 后台左上角随机显示《一首简单的歌》这首歌的歌词。

  1. 在 WordPress 目录 /wp-content/plugins/ 下新建一个文件 simple_song。
  2. 用文本编辑工具打开它,输入 <?php ?>,接下来的工作就是在这里面填写相应 PHP 代码。
  3. 首先按一定的格式编写本插件的一些信息,WordPress 读取它用于在后台显示,方便用户查看:
/*
Plugin Name: 一首简单的歌
Plugin URI: https://www.wenjiangs.com
Description: 这个插件会在后台随机显示《一首简单的歌》的歌词。
Author: 施德来
Version: 1.0
Author URI: https://www.wenjiangs.com
*/

4.编写要执行的操作:

//定义了一个字符串数组用于存储歌词
$lyrics = '一首简单的歌
这世界很复杂
你是我最珍贵的财富';
$lyrics = explode("\n", $lyrics);
//explode()是PHP内置函数,功能就是分割字符串成字符数组
$chosen = wptexturize( $lyrics[ mt_rand(0, count($lyrics) - 1) ] );
/*
给 chosen 赋一条随机的歌词 
wptexturize()在wp-includes\functions-formatting.php定义,功能:把某些特殊符号给自动转换化成标准码格式。 
mt_rand()函数返回它2个参数之间的随机值 
count()返回数组大小
*/
function a_simple_song() {
	global $chosen;
	echo "<p id='dolly'>$chosen</p>";
}
//定义了一个字符串数组用于存储歌词
$lyrics = '一首简单的歌
这世界很复杂
你是我最珍贵的财富";  
$lyrics = explode("\n", $lyrics);  
//explode()是PHP内置函数,功能就是分割字符串成字符数组  
$chosen = wptexturize( $lyrics[ mt_rand(0, count($lyrics) - 1) ] );  
/* 
给chosen赋一条随机的歌词 
wptexturize()在wp-includes\functions-formatting.php定义,功能:把某些特殊符号给自动转换化成标准码格式。 
mt_rand()函数返回它2个参数之间的随机值 
count()返回数组大小 
*/
function simple_song() {
	global $chosen;
	echo "<p id='dolly'>$chosen</p>";
}

dolly 样式表由后面定义显示歌词。

5.添加 add_action() 将 simple_song 函数 hook 到 main_foot tag 的队列中

add_action('admin_footer', 'a_simple_song');
//admin_footer.php被调用时执行这个函数
add_action('admin_head', 'dolly_css');
//admin_head.php被调用时执行dolly_css()

具体经过请参考下面的从源码解读 simple_song 插件的调用过程。这样保存为 .php 文件放到 plugins 文件夹下面,再到后台激活就可以了。

WordPress 对所有插件的读取

在文件 /wordpress/wp-admin/plugins.php 中函数

<?php function get_plugins() ?>

用来从文件系统得到所有的插件。原理很简单,就是读取 wp-content/plugins 目录下的所有 PHP 文件。这个函数允许一级的子文件夹,也就是说在 wp-content/plugins 下面的PHP文件,以及所以在此目录下的一级子文件夹内部的 PHP 文件被列作插件的候选,用下面的函数去进一步提取插件信息。这样的好处是方便用户利用文件夹来对插件进行管理和组织。

foreach($plugins as $plugin_file => $plugin_data) {
    $plugin_data['Title']       = wp_kses($plugin_data['Title'], $plugins_allowedtags);
    $plugin_data['Version']     = wp_kses($plugin_data['Version'], $plugins_allowedtags);
    $plugin_data['Description'] = wp_kses($plugin_data['Description'], $plugins_allowedtags);
    $plugin_data['Author']      = wp_kses($plugin_data['Author'], $plugins_allowedtags);
    $author = ( empty($plugin_data['Author']) ) ? " : ' <cite>' . sprintf( __('By %s'), $plugin_data['Author'] ) . '.</cite>';
}

用于从插件的头部注释中获取插件的版本、名称、作者等信息。

插件的激活与注销

Active(Deactive)插件的操作都在 plugins.php 中,比如我要激活 simsong 这个插件,最后的 URL 其实是这个样子:

http://localhost/wp-admin/plugins.php?action=deactivate&plugin=simple_song.php&_wpnonce=242c8cc3e5

其中 action 表示动作,值为 active 或者 deactivate ,而 plugin 表示动作的对象插件,此处为 simple_song.php。得到动作指令后,首先从数据库中取出当前已经激活的插件。

$active = get_option('active_plugins');

然后根据动作,重新生成已激活插件数组,和 theme 一样存入数据库,并重新加载此页。加载的时候就需要考虑这些已经激活的插件是怎么工作的了。

插件加载过程

WordPress 中的每页都会包含 wp-config.php 文件,而在 wp-config.php 的最后有这样一句:

<?php require_once(ABSPATH.'wp-settings.php'); ?>

在 wp-settings.php 文件中,可以找到以下与插件相关的代码片断:

if ( get_option('active_plugins') ) {
    $current_plugins = get_option('active_plugins');
    if ( is_array($current_plugins) ) {
		foreach ($current_plugins as $plugin) {
			if (" != $plugin && file_exists(ABSPATH . PLUGINDIR . '/' . $plugin))
			include_once(ABSPATH . PLUGINDIR . '/' . $plugin);
		}
    }
}

可见这段代码会取出系统中所有 actived 的插件,并 include 进来。所以在每页加载的时候,都会首先 include 这些插件代码。这也就是为什么在主题模板里面可以直接调用插件的函数。

通过插件机制注册系统事件

WordPress 中的很多功能也都是通过这种插件结构来实现的,WordPress 默认注册的系统事件保存在 default-filter.php 中比如:

<?php add_filter('the_content', 'convert_smilies'); ?>

用来将正文(content)中的笑脸符号转换为图像。

add_filter('comment_text', 'wptexturize');

用来将从数据库提取的正文中的特殊符号转化成标准格式的。

源码解读 simple_song 插件的调用过程

在每一个 wordpress/wp-admin/ 下面的文件(也就是后台显示需要的文件)的前面都有

<?php require_once('admin-header.php'); ?>

而在 admin-head.php 中将会执行扩展点 admin_head 的所有扩展:

<?php do_action('admin_head', "); ?>

这样就会执行所有 hook 到 admin_head 上的函数 Admin Page 的 Footer 部分同样如此,

<?php do_action('admin_footer', "); ?>

这样就会执行所有挂接到 admin_footer 的函数

simple_song 里面有这么 2 行代码:

add_action('admin_footer', 'a_simple_song');
add_action('admin_head', 'dolly_css');

将控制形式和内容 2 个函数挂到不同的 tag 上,控制文字显示位置和样式的 dolly_css 是先被调用,然后 admin_foot.php 被调用一次,simplesong() 也就被调用一次,来显示歌词。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

0 文章
0 评论
84961 人气
更多

推荐作者

醉城メ夜风

文章 0 评论 0

远昼

文章 0 评论 0

平生欢

文章 0 评论 0

微凉

文章 0 评论 0

Honwey

文章 0 评论 0

qq_ikhFfg

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文