Typecho 的整体设计和文件结构
Typecho是一个由国人开发的小型单用户博客程序。它的设计思想介于过程式编程(如Wordpress)以及现代的完全面向对象编程(如laravel框架)之间,算是一个过渡的产品。另外,Typecho整体结构设计清晰完整,代码量也不大,对于像我这样的初学者而言,为了更好的理解PHP编程的前世今生以及响应编程思想的发展,Typecho的源代码应该是一个很好的学习研究对象。
看代码先就从整体结构入手。Typecho整体的设计很有层次和条理的,整理归纳如下图:
核心层
核心层包括Typecho,IXR和CommonMark三个组件。其中Typecho是Typecho的框架层,相当于是专门为博客程序写的一个精简的框架系统。主要封装了数据库,路由,HTTP相关操作以及定义了widget和Plugin对象。
IXR是一个XML-RPC库用来远程发布文章,CommonMark是一个markdown的解析库,用来把Markdown文件渲染为html,这两个是Typecho使用到的外来第三方库。
Widget层
Widget层是在Typecho核心层上用来实现网站具体业务流程的。Typecho通过把每个小的操作都封装成Widget来保证系统的灵活性。路由系统最终是执行Widget对象的action方法,所以 Widget可以看成是“Typecho精简框架”上的MVC系统中的控制器(Controller)。
Plugin层
plugin层是为了系统的扩展性而开发的。在Typecho核心层和Widget层中作者预留了很多接口,通过plugin可以给这些接口设置回调函数来扩展整个系统。
前台后台
Typecho的前台和后台是分开来的两个系统,前台通过index.php作为唯一入口地址启动整个程序,而后台则使用admin/index.php作为唯一入口来启动后台程序。
Typecho程序启动流程
Typecho的启动代码主要在config.inc.php和index.php中,我们把两个文件的代码放在一起,来看一看具体的启动过程。
/** 定义目录相关的常量 */
define('__TYPECHO_ROOT_DIR__', dirname(__FILE__));
define('__TYPECHO_PLUGIN_DIR__', '/usr/plugins');
define('__TYPECHO_THEME_DIR__', '/usr/themes');
define('__TYPECHO_ADMIN_DIR__', '/admin/');
@set_include_path(get_include_path() . PATH_SEPARATOR .
__TYPECHO_ROOT_DIR__ . '/var' . PATH_SEPARATOR .
__TYPECHO_ROOT_DIR__ . __TYPECHO_PLUGIN_DIR__);
/** 载入Typecho核心层必要的文件 */
require_once 'Typecho/Common.php';
require_once 'Typecho/Response.php';
require_once 'Typecho/Config.php';
require_once 'Typecho/Exception.php';
require_once 'Typecho/Plugin.php';
require_once 'Typecho/I18n.php';
require_once 'Typecho/Db.php';
require_once 'Typecho/Router.php';
/** 执行系统初始化,设置全局自动载入和异常截获函数 */
Typecho_Common::init();
/** 设置并初始化数据库连接 */
$db = new Typecho_Db('Mysql', 'typecho_');
$db->addServer(array (
'host' => 'localhost',
'user' => '',
'password' => 'local',
'charset' => 'utf8',
'port' => '3306',
'database' => '',
), Typecho_Db::READ | Typecho_Db::WRITE);
Typecho_Db::set($db);
/**
由初始化组件(Widget_Init)启动Typecho,具体执行的过程有:
从数据库中取出所有设置,保存在$options中,
初始化语言包,
初始化cookie,
初始化charset,
初始化exception,
设置用户请求的URL,
**初始化路由器**,
初始化插件系统,
初始化响应头,
初始化时区,
开始会话,
开始监听缓冲区。
*/
Typecho_Widget::widget('Widget_Init');
/** 注册一个初始化插件,这里就是插件的一个入口点
如果想在程序执行前运行代码,通过插件设置这里的回调函数即可。
*/
Typecho_Plugin::factory('index.php')->begin();
/** 开始路由分发 */
Typecho_Router::dispatch();
/** 注册一个结束插件,另一个插件入口点,程序执行完后运行 */
Typecho_Plugin::factory('index.php')->end();
整个过程很清晰,先通过Typecho_Widget::widget('Widget_Init')
这个Widget做各种初始化操作,包括最重要的初始化路由表和插件系统,然后通过Typecho_Router::dispatch()
分发开始分发路由。