一直对软件的组件、插件架构非常感兴趣,我认为现在开发任何应用程序,一定要有一个架构良好的插件机制,这样可以吸引其他人来开发插件,极大的扩充 系统的功能。Eclipse就是一个非常棒的例子,几乎你想什么功能,都可以从社区中找到相应的第三方插件。Firefox也同样如此,它的插件机制非常 灵活(尤其是相对IE而言),因此Firefox社区中可以找到各种各样的插件。

1)WordPress读取所有可用的插件

  在文件“/wp-admin/includes/plugin.php”中,函数 get_plugins() 用来从文件系统得到所有的插件。原理很简单,就是读取“wp-content/plugins”目录下的所有PHP文件。这个函数允许一级的子文件夹,也 就是说在’wp-content/plugins’下面的PHP文件,以及所以在此目录下的一级子文件夹内部的PHP文件被列作插件的候选,用下面的函数 去进一步提取插件信息。这样的好处是方便用户利用文件夹来对插件进行管理和组织。
  而函数 get_plugin_data() 则用来得到插件的描述(Plugin Descriptor),主要包括插件的版本、名称、作者,等信息,而这些其实是以注释的方式存在的。用WordPress中自带的Hello插件来举例:

<?php
/*
Plugin Name: Hello Dolly
Plugin URI: http://wordpress.org/#
Description: This is not just a plugin, it symbolizes the hope and enthusiasm of an entire generation summed up in two words sung most famously by Louis Armstrong: Hello, Dolly. When activated you will randomly see a lyric from <cite>Hello, Dolly</cite> in the upper right of your admin screen on every page.
Author: Matt Mullenweg
Version: 1.5
Author URI: http://ma.tt/
*/
?>

这样,在get_plugin_data函数中,就可以来得到插件的详细信息。

<?php
function get_plugin_data( $plugin_file ) {
    $plugin_data = implode( '', file( $plugin_file ));
    preg_match( '|Plugin Name:(.*)$|mi', $plugin_data, $plugin_name );
    preg_match( '|Plugin URI:(.*)$|mi', $plugin_data, $plugin_uri );
    preg_match( '|Description:(.*)$|mi', $plugin_data, $description );
    preg_match( '|Author:(.*)$|mi', $plugin_data, $author_name );
    preg_match( '|Author URI:(.*)$|mi', $plugin_data, $author_uri );
 
    if ( preg_match( "|Version:(.*)|i", $plugin_data, $version ))
        $version = trim( $version[1] );
    else
        $version = '';
 
    $description = wptexturize( trim( $description[1] ));
 
    $name = $plugin_name[1];
    $name = trim( $name );
    $plugin = $name;
    if ('' != trim($plugin_uri[1]) && '' != $name ) {
        $plugin = '<a href="' . trim( $plugin_uri[1] ) . '" title="'.__( 'Visit plugin homepage' ).'">'.$plugin.'</a>';
    }
 
    if ('' == $author_uri[1] ) {
        $author = trim( $author_name[1] );
    } else {
        $author = '<a href="' . trim( $author_uri[1] ) . '" title="'.__( 'Visit author homepage' ).'">' . trim( $author_name[1] ) . '</a>';
    }
 
    return array('Name' => $name, 'Title' => $plugin, 'Description' => $description, 'Author' => $author, 'Version' => $version);
}
?>

2)启用 & 禁用插件

  启用(禁用)插件的操作都在Plugins.php中,比如我要Deactive “Hello”这个插件,最后的URL其实是这个样子:

http://localhost/blog/wp-admin/plugins.php?action=deactivate&plugin=hello.php

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

<?php $current = get_settings('active_plugins'); ?>

  然后根据动作,重新生成已激活插件数组,存入数据库,并重新加载此页。加载的时候就需要考虑这些已经激活的插件是怎么工作的了。
BTW:附上数据库的Options表中0插件和只有1个插件的值:
没有插件:

a:1:{i:0;s:0:"";}

只有Hello插件:

a:2:{i:0;s:0:"";i:1;s:9:"hello.php";}

3)如何加载启用的插件到系统中

  WordPress中的每页都会包含“wp-config.php”文件,而“wp-config.php”中也会自动加载“wp-settings.php”文件。在“wp-settings.php”文件中,可以找到以下与插件相关的代码片断:

<?php
if ( get_option('active_plugins') ) {
    $current_plugins = get_option('active_plugins');
    if ( is_array($current_plugins) ) {
        foreach ($current_plugins as $plugin) {
            if ( '' != $plugin && 0 == validate_file($plugin) && file_exists(WP_PLUGIN_DIR . '/' . $plugin) )
                include_once(WP_PLUGIN_DIR . '/' . $plugin);
        }
    }
}
?>

  可见,这段代码会取出系统中所有启用的插件,并包含进来。所以在每页加载的时候,都会首先包含这些插件代码。那么,这些插件自己在加载的时候都做了什么呢?

4)插件的加载

  插件的加载其实最重要的一个部分就是插件的事件注册机制,WordPress插件中的事件注册其实和Eclipse中的扩展点 (Extension-Point)机制非常相像,而这种类似“插销”、“插销座”的软件插拔方式也成为了最近软件组件架构方面应用最多的实践。
  事件注册过程中比较重要的几个函数分别是:do_action、add_action、add_filter。WordPress中默认定义了很多扩 展点(也可以叫做“钩子”),或者说注册了很多系统事件(WP中的正规叫法应该是“Action Tag”),比如“admin_head”表示Admin页面的Head输出事件,“publish_post”表示发布一篇帖子的事件等等。而插件要做 的就是扩展这些扩展点,或者说挂接这些钩子,从而实现系统的扩展功能。add_action就是通常插件扩展某个扩展点用到的函数,而do_action 是扩展点本身开始执行的函数。
  刚才说过WordPress中的每一页执行前都会Include所有Active的插件代码,而这些代码通常都会用“add_action”来将自己 的函数注册到系统的扩展点中。这样,在扩展点执行的时候,就会找到系统中所有已经挂接到这个扩展点上的插件的函数来执行之,从而扩充系统的功能。
  WordPress中的很多功能也都是通过这种插件结构来实现的,默认注册了很多系统事件,都在’default-filter.php’中。比如:

<?php add_action('publish_post', 'generic_ping'); ?>

这个是用来在发布每篇帖子的时候发送XML-RPC Ping的。再比如:

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

用来将正文(content)中的笑脸符号转换为图像。
  还是举“Hello”插件来说。Hello插件会随机的在Admin Page的右上角显示一段话,它的工作原理是这样的:
  在每一个Admin page的前面都有

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

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

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

  这样,就会执行所有挂接到admin_head的函数,Admin Page 的 Footer 部分也是类似。

5)如果插件中涉及UI

  其实是一样的。以WordPress FeedBurner Plugin中添加菜单为例。
  如果想添加一个菜单,就需要注册“admin_menu”这个Action Tag(系统事件)即可:

<?php add_action('admin_menu', 'ol_add_feedburner_options_page'); ?>

  插件中的这个函数为:

<?php
function ol_add_feedburner_options_page() {
    if (function_exists('add_options_page')) {
        add_options_page('FeedBurner', 'FeedBurner', 8, basename(__FILE__), 'ol_feedburner_options_subpanel');
    }
}
?>

  “add_options_page”这个函数就会在系统的“Options”菜单中添加“FeedBurner”这样一个子菜单。

6)其它

  还有一些简单的插件就是只提供一些API函数。比如Most_Commented Plugin,它提供一个API “mdv_most_commented”:通过数据库查询得到评论最多的文章,并加以显示。因为这个插件已经被Include过,所以可以用这个API 来进行显示。

转载于:https://www.cnblogs.com/vicenteforever/articles/1867214.html

解析 WordPress 插件机制相关推荐

  1. Atitit 插件机制原理与设计微内核 c# java 的实现attilax总结

    Atitit 插件机制原理与设计微内核 c# java 的实现attilax总结 1. 微内核与插件的优点1 2. 插件的注册与使用2 2.1. Ioc容器中注册插件2 2.2. 启动器微内核启动3 ...

  2. iOS之深入解析CocoaPods的插件机制和如何加载插件整合开发工具

    一.CocoaPods 插件机制 ① Ruby 在 Ruby 中,类永远是开放的,总是可以将新的方法加入到已有的类中,除了自己的代码中,还可以用在标准库和内置类中,这个特性被称为 Ruby Open ...

  3. 【问链-EOS公开课】第十三课 EOS插件机制深入解析

    插件体系 EOS插件由三层类来实现. 最顶层是抽象类abstract_plugin,定义了插件的基本接口. 中间层是插件模板类plugin,主要用来解决插件之间依赖调用. 最底层是具体插件类,专注单个 ...

  4. Wordpress插件检测机制原理

    Wordpress插件界面里,这些用户自定义的plugin是从哪里来的? 在Wordpress目录下面有一个文件夹叫做plugins,这里面的所有文件都成为Wordpress扫描plugin的cand ...

  5. c++插件化 NDD源码的插件机制实现解析

    插件机制是一种框架,允许开发人员简单地在应用程序中添加或扩展功能.它使广泛使用,因为它可以作为模块被重复使用,并使它们更易于维护和扩展,因此它们在应用程序中非常有用.插件机制允许管理员在需要时轻松安装 ...

  6. mixin机制 vue_读?VuePress(四)插件机制

    前言 从 9 月份开始,vuepress 源码进行了重新设计和拆分.先是开了个 next 分支,后来又合并到 master 分支,为即将发布的 1.x 版本做准备. 最主要的变化是:大部分的全局功能都 ...

  7. MyBatis 源码分析 - 插件机制

    1.简介 一般情况下,开源框架都会提供插件或其他形式的拓展点,供开发者自行拓展.这样的好处是显而易见的,一是增加了框架的灵活性.二是开发者可以结合实际需求,对框架进行拓展,使其能够更好的工作.以 My ...

  8. wordpress 插件_如何为您的Web应用程序创建WordPress插件

    wordpress 插件 by Feedier by Alkalab 由Feedier通过Alkalab 如何为您的Web应用程序创建WordPress插件 (How to create a Word ...

  9. PHP中插件机制的一种实现方案

    插件,亦即Plug-in,是指一类特定的功能模块(通常由第三方开发者实现),它的特点是:当你需要它的时候激活它,不需要它的时候禁用/删除它:且无 论是激活还是禁用都不影响系统核心模块的运行,也就是说插 ...

最新文章

  1. SQLServer学习-- SQLServer
  2. 如何高性能添加UIView阴影
  3. DOSbox汇编环境配置
  4. 如何自学Android
  5. Linux系统下安装卸载jdk
  6. Spring Cloud原理
  7. dedeCMS会员注册功能,如何开启或关闭?
  8. String常见问题
  9. 如何阻止分布式拒绝服务***
  10. 手写bind_这些手写代码会了吗?少年
  11. python交通流预测算法_对各种交通流预测模型的简要分析
  12. 非线性数学模型线性化
  13. 【Excel VBA】一键取消excel中所有隐藏sheet
  14. 松翰单片机数码管c语言,松翰单片机数码管程序
  15. 矩阵基础概念之行列式与秩
  16. java计算机毕业设计晨光文具店进销存系统设计与开发源码+数据库+系统+lw文档+部署
  17. 微博视频自动投稿视频社区大师软件下载
  18. 嵌入式微处理器的体系结构
  19. 在AWS Lambda上部署标准FFmpeg工具——Docker方案
  20. 存储历史(从古老的绳子记忆到如今)

热门文章

  1. 自定义sort函数第三个参数的规则
  2. UI5 Source code map机制的细节介绍
  3. Cocos Creator导出场景和预制的问题
  4. CGImageRef 图片压缩 裁减
  5. linux上用mplayer播放cue文件的设想
  6. 激光光凝后容易出现频繁闪光的原因
  7. 人一生中最大的遗憾应该是什么
  8. flask和vue的冲突问题
  9. synaptic不停抖动后自动关闭的问题
  10. intellij2018修改代码背景颜色