本站架构之一


这是本系列的第一篇,用于说明这个站点的设计思路.算是概述.

第一个思路是,这个站点不使用数据库,也就是说这个网站的数据是基于文件系统的.目的是轻量,简单.

站点的主要目的在于发布文章,就是blogging,因此文章就是主要数据,一篇博文用一个目录来存储,目录中有一个config.xml文件来描述该文章的相关信息,例如标题,作者,日期.正文用一个php文件来存储.所以数据是自描述的,分散存储的,没有集中在一个数据中心,在以数据库为存储机制的实现中,数据被统一存放在数据库中,我的做法是每个实体数据独立的存在,用一个文本文件描述关于自己的信息,程序则会去解读这些信息.这样做的主要目的是为了方便的进行手动编辑,这样可以使用任何喜欢的文本处理工具.如果用数据库的话,就很难实现这一点,通常必须是某个定义好的网页编辑器,或者系统后台,这些界面都是固定的,无法改变的.

先看配置文件的格式,这个文件起着核心的作用.下面是一个样例

<?xml version="1.0" encoding="utf-8"?>
<post>
  <title>本站架构之一</title>
  <author>deepdiscuz</author>
  <date>
    <year>2011</year>
    <month>2</month>
    <day>28</day>
  </date>
  <interpreter>default</interpreter>
  <category>本站架构</category>
  <previewimg>noimage</previewimg>
  <previewtext>previewtext.php</previewtext>
  <content>content.php</content>
  <comment>
    <commentcount>0</commentcount>
    <commentpages></commentpages>
  </comment>
</post>

这里重点要看的是interpreter的概念,这个系统有过第一版,是没有这个概念的,那时也没有使用PHP的类,完全是过程式的,以程序为核心的,结果很难扩展,很多东西都被定死了,每添加一点功能代码就更加混乱.

interpreter的意思表示数据希望使用哪个解释器来解释这份数据,一个解释器被实现为一个类.这样就给数据可能具有的格式提供了无限的变化空间,因为如果采用了新的格式,只需要使用新的解释器就可以了.现在是程序依赖于数据,所以第二个思路是以数据为中心.

interpreter是一个名字,这个名字同时关联到包含该类的PHP文件,也和类名有关联,即根据这个名字会包含对应的文件,使用new创建实例的时候所使用的类名也是和inerpreter相关联的.下面的代码创建解释器的实例.

<?php

// for all
require_once($_SERVER["DOCUMENT_ROOT"]."\\public\\common_functions.php");
require_once($_SERVER["DOCUMENT_ROOT"]."\\public\\config.php");

// dao
require_once($_SERVER["DOCUMENT_ROOT"]."\\public\\class_ArticleConfig.php");
$data new  ArticleConfig();// 该脚本被包含的目录下的config.xml
// interpreter
$interperter// hold the instance of interpreter class instance
require_once($_SERVER["DOCUMENT_ROOT"]."\\public\\".$data->getInterpreter()."_interpreter.php");

// 实际上,这相当于一个配置文件,一个名字到类名的映射
function classFactory($interpreter_name)
{
    global $data;
    switch $interpreter_name )
    {
        case 'default':
            return new DefaultInterpreter($data);
        case 'wide':
            return new WideInterpreter($data);
        default:
            return new DefaultInterpreter($data);
    }

}
$interpreter = classFactory($data->getInterpreter());
$interpreter->render();
?>

其中getInterpreter函数返回的就是interpreter标签中的名字.类文件名格式是 interpretername_interpreter.php. new 操作符得到一个实例之后,剩下的工作就是调用其render函数,也可以叫做interpret,解释的实际活动就是渲染HTML页面.

这里ArticleConfig是对xml文件的封装,相当于DAO,下一篇会详述.

最后快速的浏览一下其他字段的含义.日期中年月日必填,其他的可以选填,不填的话默认值是0.interpreter也可以不填,DAO会判断这种情况并返回一个默认值.category,文章的所属分类,这里没有创建一个分类的概念,当填写一个类别的名字的时候就等于创建了一个分类,结果会自动反应到页面上,在数据库的实现中通常需要一个table,例如表名是category,你需要先创建一个分类,然后写文章的时候选择那个分类.previewimg,显示列表的时候作为预览图,previewtext一个php文件,预览文本,在合适的地方被包含,content.php 正文内容,在合适的地方被包含.