• 推荐 1 推荐
  • 收藏 14 收藏,3.7k 浏览

上一次说了 Typecho 大致的流程,今天简单说一下插件机制和插件的编写方法。

还是先上index.php

if (!@include_once 'config.inc.php') {
file_exists('./install.php') ? header('Location: install.php') : print('Missing Config File');
exit;
} /** 初始化组件 */
Typecho_Widget::widget('Widget_Init'); /** 注册一个初始化插件 */
Typecho_Plugin::factory('index.php')->begin(); /** 开始路由分发 */
Typecho_Router::dispatch(); /** 注册一个结束插件 */
Typecho_Plugin::factory('index.php')->end();

细心的朋友可能会发现上一次

/** 注册一个初始化插件 */
Typecho_Plugin::factory('index.php')->begin(); /** 注册一个结束插件 */
Typecho_Plugin::factory('index.php')->end();

这两行代码我们并没有提起,这是为什么呢?这是因为上一期主要是分析系统执行流程,我们假设没有安装任何插件,而在没有安装插件的情况下这两行代码是没有任何作用的。

众所周知,目前大部分插件都采用钩子机制,Typecho也不例外,这两行代码就是系统在index.php里预先设定的两个插件接口,分别是整个程序流程中第一个和最后一个接口。那这种插件接口是怎么执行的呢?


我们以 HelloWorld 插件为例,HelloWorld 插件所使用的接口在 admin/menu.php,代码如下:

<?php Typecho_Plugin::factory('admin/menu.php')->navBar(); ?>

HelloWorld 插件的代码,在 usr/plugins/HelloWorld/Plugins.php :

<?php
/**
* Hello World
*
* @package HelloWorld
* @author qining
* @version 1.0.0
* @link http://typecho.org
*/
class HelloWorld_Plugin implements Typecho_Plugin_Interface
{
/**
* 激活插件方法,如果激活失败,直接抛出异常
*
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function activate()
{
Typecho_Plugin::factory('admin/menu.php')->navBar = array('HelloWorld_Plugin', 'render');
} /**
* 禁用插件方法,如果禁用失败,直接抛出异常
*
* @static
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function deactivate(){} /**
* 获取插件配置面板
*
* @access public
* @param Typecho_Widget_Helper_Form $form 配置面板
* @return void
*/
public static function config(Typecho_Widget_Helper_Form $form)
{
/** 分类名称 */
$name = new Typecho_Widget_Helper_Form_Element_Text('word', NULL, 'Hello World', _t('说点什么'));
$form->addInput($name);
} /**
* 个人用户的配置面板
*
* @access public
* @param Typecho_Widget_Helper_Form $form
* @return void
*/
public static function personalConfig(Typecho_Widget_Helper_Form $form){} /**
* 插件实现方法
*
* @access public
* @return void
*/
public static function render()
{
echo '<span class="message success">' . Typecho_Widget::widget('Widget_Options')->plugin('HelloWorld')->word . '</span>';
}
}

Typecho 在数据库 Options 表里,有一个名为 plugins 字段,里边记录了整个程序已激活插件的接口挂载情况,没有激活任何插件时 plugins 字段是这样的:

Array
(
[activated] => Array
(
) [handles] => Array
(
)
)

接下来我们激活程序自带的 HelloWorld 插件看看有什么变化,激活后 plugins 字段变为:

Array
(
[activated] => Array
(
[HelloWorld] => Array
(
[handles] => Array
(
[admin/menu.php:navBar] => Array
(
[0] => Array
(
[0] => HelloWorld_Plugin
[1] => render
) ) ) ) ) [handles] => Array
(
[admin/menu.php:navBar] => Array
(
[0] => Array
(
[0] => HelloWorld_Plugin
[1] => render
) ) )
)

可以看出,激活插件后,程序根据插件的激活函数

    public static function activate()
{
Typecho_Plugin::factory('admin/menu.php')->navBar = array('HelloWorld_Plugin', 'render');
}

系统在数据库中将 HelloWorld 插件与 ('admin/menu.php')->navBar() 接口作了关联,
而具体关联的则是 HelloWorld_Plugin 类的 render 函数。


其实到这里大家也能看出个大概,我们访问系统后台的时候,当执行到

<?php Typecho_Plugin::factory('admin/menu.php')->navBar(); ?>

这句代码时:

  • 从数据库 plugins 字段里检索,检索到 [admin/menu.php:navBar] 下挂载了一个插件,具体为HelloWorld_Plugin 类的 render 函数,系统执行之并输出 HelloWorld 在后台的导航栏。

  • 那么如果检索不到有任何插件挂载呢,程序不执行任何动作并执行下边的代码,这也就是为什么在分析系统流程时可以直接将插件接口的代码略过的原因。


整个程序中关键的地方设置了很多类似的插件接口,方便通过编写插件而不修改程序源代码来完成我们特定的功能,设置插件接口的方法有两种:

  • 一种是 Typecho_Plugin::factory,在 var/Typecho/Plugin.php 中定义

  • 另一种是 $this->pluginHandle(), 在 var/Typecho/Widget.php 中定义

第二种是可以传递参数的接口,这个以后再说。


最后不禁有人要问,程序中设定这么多接口,即使一个插件也没安装也要挨个执行吗,效率得多低?

答案是肯定的,必须得执行,不过数据库也只读取一次,然后存在内存里,以后的每次查询都是在内存对比,多执行两行php代码基本没效率影响。具体速度咋样,用过 wp 的你懂的~~

下一节,根据具体接口,演示插件编写~

typecho流程原理和插件机制浅析(第二弹)的更多相关文章

  1. typecho流程原理和插件机制浅析(第一弹)

    typecho流程原理和插件机制浅析(第一弹) 兜兜 393 2014年03月28日 发布 推荐 5 推荐 收藏 24 收藏,3.5k 浏览 虽然新版本0.9在多次跳票后终于发布了,在漫长的等待里始终 ...

  2. Cocoapods插件机制浅析

    原文链接 背景 虽然做iOS开发的过程中使用过 Cocoapods, 但是对里面的细节了解其实不算太多,直到这两年做织女项目时,通过对Cocoapods进行Qt支持改造才开始深入了解部分细节,这个过程 ...

  3. Dubbo原理和源码解析之“微内核+插件”机制

    github新增仓库 "dubbo-read"(点此查看),集合所有<Dubbo原理和源码解析>系列文章,后续将继续补充该系列,同时将针对Dubbo所做的功能扩展也进行 ...

  4. mybatis插件机制及分页插件原理

    MyBatis 插件原理与自定义插件: MyBatis 通过提供插件机制,让我们可以根据自己的需要去增强MyBatis 的功能.需要注意的是,如果没有完全理解MyBatis 的运行原理和插件的工作方式 ...

  5. mybatis(六)插件机制及分页插件原理

    转载:https://www.cnblogs.com/wuzhenzhao/p/11120848.html MyBatis 通过提供插件机制,让我们可以根据自己的需要去增强MyBatis 的功能.需要 ...

  6. Omi框架学习之旅 - 插件机制之omi-finger 及原理说明

    以前那篇我写的alloyfinger源码解读那篇帖子,就说过这是一个很好用的手势库,hammer能做的,他都能做到, 而且源码只有350来行代码,很容易看懂. 那么怎么把这么好的库作为omi库的一个插 ...

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

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

  8. WordPress 插件机制的简单用法和原理(Hook 钩子)

    WordPress 的插件机制实际上只的就是这个 Hook 了,它中文被翻译成钩子,允许你参与 WordPress 核心的运行,是一个非常棒的东西,下面我们来详细了解一下它. PS:本文只是简单的总结 ...

  9. php插件机制实现原理

    插件,亦即Plug-in,是指一类特定的功能模块(通常由第三方开发者实现) 它的特点: 1. 随时安装.卸载.激活.禁用 2. 无论什么状态都不影响系统核心模块的运行, 3. 是一种非侵入式的模块化设 ...

随机推荐

  1. UML从需求到实现---类图(2)

    上节写到了UML中的类图:UML从需求到实现---类图(1) 写完以后总觉得写的不够详细.里面很多细节没有说到.一篇文章就把强大的面向对象的类说完.当然是不可能的.这次我再补充一些关于UML中类图和类 ...

  2. hdu 4280 最大流sap

    模板套起来 1 5 7 //5个结点,7个边 3 3 //坐标 3 0 3 1 0 0 4 5 1 3 3 //相连的结点和流 2 3 4 2 4 3 1 5 6 4 5 3 1 4 4 3 4 2 ...

  3. Linux下打包压缩war和解压war包

    Linux下打包压缩war和解压war包 unzip是一种方法,如果不行则采用下面的方法 把当前目录下的所有文件打包成game.war jar -cvfM0 game.war ./ -c   创建wa ...

  4. Effective C++笔记:设计与声明

    条款18:让接口容易被正确使用,不易被误用 1,好的接口很容易被正确使用,不容易被误用.你应该在你的所有接口中努力达成这些性质. 2,“促进正使用”的办法包括接口的一致性,以及与内置类型的行为兼容. ...

  5. 【分享送书】NGUI全面实践教程V3.8.2 活动开始了!!

    [分享送书]NGUI全面实践教程V3.8.2 活动开始了!! 活动奖品:   活动地址:http://dwz.cn/JHdlu

  6. 递推DP URAL 1225 Flags

    题目传送门 /* 1 r; 2 b; 3 w 2不能在最前面,所以dp[1] = 2; dp[2] = 2: 13 or 31 dp[i] = dp[i-1] + dp[i-2]; 只加1或3时,总数 ...

  7. 游戏 window

    using UnityEngine; using System.Collections; public class YY : MonoBehaviour { ,,,); ,,,); // Use th ...

  8. 游戏 tabpanel

    using UnityEngine; using System.Collections; public class La : MonoBehaviour { private int select; p ...

  9. BZOJ2773 : ispiti

    首先询问i相当于询问a[j]>=a[i],b[j]>=b[i]的j 如果b[j]==b[i],那么a[j]>a[i],这种情况先用set处理掉 如果b[j]>b[i],那么a[ ...

  10. Vijos 1100 (区间DP)

    题目链接: https://vijos.org/p/1100 题目大意:NOIP著名的加分二叉树.给出一棵树的中序遍历,加分规则左子树*右子树+根.空子树分数为1.问最大加分的树结构,输出树结构的先序 ...