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

简介: typecho流程原理和插件机制浅析(第二弹) 兜兜 393 2014年04月02日 发布 推荐 1 推荐 收藏 14 收藏,3.7k 浏览 上一次说了 Typecho 大致的流程,今天简单说一下插件机制和插件的编写方法。
  •  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 的你懂的~~

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

目录
相关文章
|
7月前
|
存储 移动开发 开发框架
使用UniApp实现视频数组自动下载与播放功能:一步步指导
使用UniApp实现视频数组自动下载与播放功能:一步步指导
153 0
|
11天前
|
开发框架 前端开发 开发者
【Uniapp 专栏】Uniapp 的状态管理功能深度解析
【5月更文挑战第13天】Uniapp 的状态管理对于构建复杂跨平台应用至关重要,它包括全局变量、Vuex 风格管理。核心概念有 State、Actions 和 Mutations。通过状态定义、动作设计和突变管理,提高开发效率和代码可维护性。实际案例和与其他框架比较显示了 Uniapp 的优势。理解并有效利用状态管理,能提升应用质量和开发效率。
【Uniapp 专栏】Uniapp 的状态管理功能深度解析
|
11天前
|
小程序 JavaScript 前端开发
【经验分享】如何实现小程序代码热更新| 江海计划
【经验分享】如何实现小程序代码热更新| 江海计划
59 7
|
11天前
|
存储 监控 安全
插件机制详解:原理、设计与最佳实践
插件机制详解:原理、设计与最佳实践
134 0
|
9月前
|
前端开发
前端学习笔记202307学习笔记第五十六天-搭建react源码调试环境2创建环境
前端学习笔记202307学习笔记第五十六天-搭建react源码调试环境2创建环境
44 0
|
9月前
|
前端开发
前端学习笔记202307学习笔记第五十六天-搭建react源码调试环境1创建环境
前端学习笔记202307学习笔记第五十六天-搭建react源码调试环境1创建环境
48 0
|
9月前
|
前端开发
前端学习笔记202307学习笔记第五十六天-搭建react源码调试环境3创建环境
前端学习笔记202307学习笔记第五十六天-搭建react源码调试环境3创建环境
51 0
|
SQL JSON 机器人
pytest+yaml设计接口自动化框架过程记录(一步一步记录如何设计,完结撒花),源码提供,视频教程
pytest+yaml设计接口自动化框架过程记录(一步一步记录如何设计,完结撒花),源码提供,视频教程
|
SQL 安全 网络安全
Yii2.0网站如何才能让安全最大化?具体步骤是怎样的?底层原理是什么?
Yii2.0网站如何才能让安全最大化?具体步骤是怎样的?底层原理是什么?
|
JavaScript 知识图谱
修改第三方插件或库的源码经验技巧总结
修改第三方插件或库的源码经验技巧总结
修改第三方插件或库的源码经验技巧总结