转载请注明出处:http://blog.csdn.net/jh_zzz

以 index.php 为例:

/** 初始化组件 */

Typecho_Widget:: widget('Widget_Init' );

Init 的 execute 中会初始化 Typecho_Plugin ,这里 $options -> plugins 是从数据库读出来后反序列化的:

Typecho_Plugin:: init($options -> plugins);

init 中分别将 plugins 中的 activated 和 handles 单独保存,打印出来形式是这样的:

[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

)

)

)

继续看 index.php :

/** 注册一个初始化插件 */

Typecho_Plugin:: factory('index.php' )-> begin();

… 略过 …

/** 注册一个结束插件 */

Typecho_Plugin:: factory('index.php' )-> end();

Typecho_Plugin:: factory 会根据 ’index.php’ 创建一个新的 Typecho_Plugin 。接下来的 begin() , end() 实际上都是不存在的,于是魔鬼方法 __call 被执行,

$component $this -> _handle ':' $component ;

$last count($args );

$args [$last $last $args [0 ] false ;

if (isset (self:: $_plugins ['handles' ][$component ])) {

$args [$last NULL ;

$this -> _signal true ;

foreach (self:: $_plugins ['handles' ][$component ] as $callback ) {

$args [$last call_user_func_array($callback $args );

}

}

__call 查找对应 index.php:begin 的 Typecho_Plugin ,如果找到的话,就会调用相应的方法。例如如果找到的是HelloWorld_Plugin ,则 HelloWorld_Plugin.render() 会被执行。

(

[0] => HelloWorld_Plugin

[1] => render

)

简单说一下 Plugin 是如何加载的,在 config.inc.php 中首先设置了包含路径,插件路径也在其中:

/** 设置包含路径 */

set_include_path(get_include_path() PATH_SEPARATOR .

__TYPECHO_ROOT_DIR__ '/var' PATH_SEPARATOR .

__TYPECHO_ROOT_DIR__ __TYPECHO_PLUGIN_DIR__ );

HelloWorld_Plugin 此时尚未被加载,所以当执行到 HelloWorld_Plugin.render() 时 ,Typecho_Common::__autoLoad 函数被执行,这里会自动加载指定的插件文件:

include_once str_replace('_' , '/' , $className '.php' ;

例如对于 HelloWorld_Plugin ,文件就是 HelloWorld/Plugin.php ,因为 usr/plugin 目录已经在包含的路径中,所以这个文件可以正常加载。

当初我学习 php 的时候还是 php3 ,现在一些新特性我都不知道,这一段我看了半天才搞清楚,这次读这些代码了解了不少 php 的新特性:)

Typecho 代码阅读笔记(三) - 插件机制的更多相关文章

  1. Typecho 代码阅读笔记(一) - 页面渲染及路由机制

    转载请注明出处:http://blog.csdn.net/jh_zzz 从 index.php 开始看, /** 初始化组件 */ Typecho_Widget:: widget('Widget_In ...

  2. Typecho 代码阅读笔记(二) - 数据库访问

    转载请注明出处:http://blog.csdn.net/jh_zzz 这一块比较复杂,我还没有完全理解为什么要把 SQL 语句的组装搞这么复杂. 从一个普通皮肤页面开始 themes/default ...

  3. <<梦断代码>>阅读笔记三

    看完了这最后三分之一的<梦断代码>,意味着这本软件行业的著作已经被我粗略地过了一遍. 在这最后三分之一的内容中,我深入了解了在大型软件项目的运作过程中存在的困难和艰辛.一个大型软件项目的成 ...

  4. Mongodb源代码阅读笔记:Journal机制

    Mongodb源代码阅读笔记:Journal机制 Mongodb源代码阅读笔记:Journal机制 涉及的文件 一些说明 PREPLOGBUFFER WRITETOJOURNAL WRITETODAT ...

  5. Linux协议栈代码阅读笔记(二)网络接口的配置

    Linux协议栈代码阅读笔记(二)网络接口的配置 (基于linux-2.6.11) (一)用户态通过C库函数ioctl进行网络接口的配置 例如,知名的ifconfig程序,就是通过C库函数sys_io ...

  6. [置顶] Linux协议栈代码阅读笔记(一)

    Linux协议栈代码阅读笔记(一) (基于linux-2.6.21.7) (一)用户态通过诸如下面的C库函数访问协议栈服务 int socket(int domain, int type, int p ...

  7. [置顶] Linux协议栈代码阅读笔记(二)网络接口的配置

    Linux协议栈代码阅读笔记(二)网络接口的配置 (基于linux-2.6.11) (一)用户态通过C库函数ioctl进行网络接口的配置 例如,知名的ifconfig程序,就是通过C库函数sys_io ...

  8. Linux-3.0.8 input subsystem代码阅读笔记

    先乱序记录一下阅读Linux input subsystem代码的笔记. 在input device driver的入口代码部分,需要分配并初始化input device结构,内核提供的API是inp ...

  9. 论文阅读笔记三十七:Grid R-CNN(CVPR2018)

    论文源址:https://arxiv.org/abs/1811.12030 开源代码:未公开 摘要 本文提出了目标检测网络Grid R-CNN,其基于网格定位机制实现准确的目标检测.传统方法主要基于回 ...

随机推荐

  1. Effective Java2读书笔记-类和接口(五)

    第21条:用函数对象表示策略 这一条其实也没说啥,就是策略模式.碰到这种场景时,定义一个策略接口,然后不同策略子类实现它,主类包含这个接口的引用就可以了. 第22条:优先考虑静态成员类 嵌套类是指被定 ...

  2. Uva272.TEX Quotes

    题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  3. 学艺不精,又被shell的管道给坑了

    我用过bash shell,而且时间不短了.但我从来没学过shell,至少没有像C++这么认真去学.平时写些基本的脚本没问题,不懂也可以google.百度.可在2014最后一天,掉坑里了. 其实脚本也 ...

  4. phpcms加载系统类与加载应用类之区别详解

    <?php 1. 加载系统类方法load_sys_class($classname, $path = ''", $initialize = 1)系统类文件所在的文件路径:/phpcms ...

  5. 一个简单的面试题 很多人也会懵 i++ 和++i的区别

    以下分别输出i的值分别为多少 NSInteger i = 0 ; NSLog(@"%ld",i++); NSLog(@"%ld",i++); NSLog(@&q ...

  6. Hibernate(三)——框架中的关系映射

    在设计数据库时我们会考虑,表与表之间的关系,例如我们前边经常提到的一对一,一对多,多对多关系,在数据库中我们通过外键,第三张表等来实现这些关系.而Hibernate时间实体类和数据库中的表进行的映射, ...

  7. Android学习总结——实时显示系统时间

    我们都知道System.currentTimeMillis()可以获取系统当前的时间,这里要实时显示就可以开启一个线程,然后通过handler发消息,来实时的更新TextView上显示的系统时间.具体 ...

  8. java与.net比较学习系列(4) 运算符和表达式

    上一篇总结了java的数据类型,得到了冰麟轻武等兄弟的支持,他们提出并补充了非常好的建议,在这里向他们表示感谢.在后面的文章中,我会尽力写得更准确和更完善的,加油! 另外,因为C#是在java之后,也 ...

  9. COCOS2D-X 不反复随机数

    srand(time(NULL)); int a[5]; for(int i=0;i<5;i++) { a[i]=CCRANDOM_0_1()*5; } srand放在循环外面

  10. Udacity调试课笔记之断言异常

    Udacity调试课笔记之断言异常 这一单元的内容不是很多,如Zeller教授所说,就是如何写.检查断言,并如何使用工具实现自动推导出断言的条件. 现在,多数的编程语言,尤其是高级编程语言都会有内置的 ...