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

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

兜兜 393 2014年04月02日 发布

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

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

还是先上index.php

if ([email protected]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 的你懂的~~

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

时间: 2024-10-29 19:10:59

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

深入解读PHP插件机制原理

深入解读PHP插件机制原理 PHP插件机制是指一类特定的功能模块,主要特点有:可以随时激活删除使用,灵活性较强.大家可以在文章中获得这一机制的相关知识. AD:51CTO移动APP安全沙龙!马上要爆满,手慢没座位! 我们在这篇文章中主要向大家讲了一些PHP插件机制的实现方法.希望大家可以通过本问介绍的内容初步了解对PHP插件机制的认识. PHP函数restore()重置PHP配置环境 PHP数据缓存类必要性分析 PHP创建PPT文档范例解析 总结各种不同PHP控制语句 PHP INCLUDE语句

基于接口的插件机制

一.前言 插件,意味着可扩展,且宿主程序不依赖于插件,即插即用.这种软件设计方式可以使我们的应用程序最大化地获得可扩展性.适应性和稳定性,而且便于软件的维护和升级.在什么场景下使用插件呢?例如在本篇文章中,我个人有一个小需求就是希望记事本带行号,于是我自己写了一个极简易的编辑器(CodeEditor),以这个编辑器为例,主体程序功能包括常见的新建.复制.查找.保存等已经完成,但是在使用的过程中发现需要用到 格式化 这个功能,但是我还不想再去改主程序,这种情形下就可以通过插件来实现,这样以后在使用

Android 插件化原理解析——插件加载机制

上文 Activity生命周期管理 中我们地完成了『启动没有在AndroidManifest.xml中显式声明的Activity』的任务:通过Hook AMS和拦截ActivityThread中H类对于组件调度我们成功地绕过了AndroidMAnifest.xml的限制. 但是我们启动的『没有在AndroidManifet.xml中显式声明』的Activity和宿主程序存在于同一个Apk中:通常情况下,插件均以独立的文件存在甚至通过网络获取,这时候插件中的Activity能否成功启动呢? 要启动

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

Atitit 插件机制原理与设计微内核 c# java 的实现attilax总结 1. 微内核与插件的优点1 2. 插件的注册与使用2 2.1. Ioc容器中注册插件2 2.2. 启动器微内核启动3 3. 插件的俩种执行策略3 3.1. 必须手动接续,否则自动终止(推荐)3 3.2. 必须手动throw  stop ex终止,负责自动接续..4 4. 插件链的生成原理4 5. -------code4 6. 参考7 1. 微内核与插件的优点 但凡有生命力的产品,都是在扩展性方面设计的比较好的,因

php中的插件机制原理和实例

PHP中的插件机制原理和实例 投稿:junjie 字体:[增加 减小] 类型:转载 这篇文章主要介绍了PHP中的插件机制原理和实例,文中例子主要借鉴了网上一些网友的方式做了稍微的改造,需要的朋友可以参考下 PHP项目中很多用到插件的地方,更尤其是基础程序写成之后很多功能由第三方完善开发的时候,更能用到插件机制,现在说一下插件的实现.特点是无论你是否激活,都不影响主程序的运行,即使是删除也不会影响. 从一个插件安装到运行过程的角度来说,主要是三个步骤: 1.插件安装(把插件信息收集进行采集和记忆的

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

WordPress 的插件机制实际上只的就是这个 Hook 了,它中文被翻译成钩子,允许你参与 WordPress 核心的运行,是一个非常棒的东西,下面我们来详细了解一下它. PS:本文只是简单的总结一下,更多用法还是要参考文中给出的函数. 钩子分类 钩子分为两种,一种叫做动作(action),还有一种叫做过滤器(filter).这两种钩子实现原理基本一样,后边会讲到,使用上的区别在于过滤器有返回值,而动作没有. 动作的理念是让你在一种情况或者一个特别的位置执行一些函数,比如发送一封邮件等:过滤

mybatis插件机制原理

mybatis插件机制及分页插件原理 参考链接:mybatis插件机制及分页插件原理 如何编写一个自定义mybatis插件 参考链接:mybatis 自定义插件的使用 原文地址:https://www.cnblogs.com/jxxblogs/p/12150439.html

行为扩展以及插件机制

在thinkPHP中的行为扩展和插件机制. 首先行为扩展这个概念是TP框架的核心组成之一,关于行为的解释我就粗略的概括一下吧: TP在从接受到HTTP请求到最终将试图输出,期间经历的很多步骤,这些步骤大家可以在http://document.thinkphp.cn/manual_3_2.html#system_process这里面看到. 那么行为扩展实际上就是在这些流程里面买下了一个钩子,你可以往钩子里添加你自己的业务逻辑 当程序执行到某些钩子位置时将自动触发你的业务逻辑,http://docu

xadmin的插件机制

xadmin的视图方法中如果加了@filter_hook 标记的都可以作为插件的钩子函数. 例如在ListAdminView类中有许多加了上述标记的方法, @filter_hook def get_context(self): """ Prepare the context for templates. """ self.title = _('%s List') % force_unicode(self.opts.verbose_name) mo