编者按:Discuz! X2.5 RC 版本已于上周发布,《站长》 杂志首次连线 Discuz!
开发人员,为站长详细解读 Discuz! X2.5 在系统架构、性能负载、功能组件、应用中心等方面的特色与改进。小编特别请到了 Discuz!
开发组成员 bilicen,由他为我们介绍开发人员倾注大量时间与精力进行代码重构的底层架构。

《站长》:bilicen 你好!Discuz! X2.5 在系统架构方面进行了哪些改进呢?

bilicen:我们主要进行了六个方面的改进,主要包括:

1 、程序底层架构的改进;2 、用户输入数据的处理;3 、数据库 DB 层的改进;4 、内存级缓存层的优化;5 、多服务器分库分布式部署;6 、主要性能瓶
颈点的优化。经过这六个方面的改进,Discuz!
X2.5 的系统架构全新改造,承载能力更强了,并且支持各种第三方插件、模板的扩展,能适应论坛未来的发展需要。

《站长》:为什么要对系统架构进行如此大幅的改动呢?

Bilicen:站长的需求是无限的,而论坛功能是有限的,论坛系统架构的承载能力更加有限。为了满足更多站长
需求,首先就要改变系统架构。之前的论坛版本更像是普通货轮,它承载的货物有限;而 Discus!
X2.5 就像是诺亚方舟,它可承载多种多样的事物,表现在论坛层面就是新版支持站长需要的各种功能、插件与拓展。

《站长》:在系统架构的六个方面改进中,能否为我们选取一点着重介绍下?

Bilicen:这里我着重介绍下 Discus! X2.5 在底层架构方面的改进吧,也就是加固 Discuz!

X2.5 方舟骨架。首先,我们要求 PHP 版本大于 5.1,抛弃了对 PHP4 的支持;其次,我们大量使用了面向对象编程 (OOP),使代码的重用性和维护性
更高;再次,实现了程序运程过程中按需加载,减少一个进程中对非必要的文件的解析,按需加载主要是针对类文件;最后,为了实现程序的按需加载,对目录名、
文件名和类名的要求如下:

类文件存在/source/class
目录中,类名和文件名相同,一个类一个文件,类名以下划线 (_) 分隔,第一个下划线之前部分为目录名,没有下划线的类名直接放/source/class
/目录下。产品中个别特殊类由于历史原因无法实现自动加载,需手动处理 include 或 require 。

《站长》:在底层架构的改进中,肯定会涉及一些核心文件的改造吧,那主要的改造思路是什么呢?

Bilicen:主要改造思路是采用新的底层架构接口,以及避免底层架构的臃肿。我们改造了 class_core.php 入口文件以及 function_core.php 减肥之术等 2 个核心文件。关于这方面代码有兴趣的朋友可参考我提供的附件 (附 1) 。

《站长》:在数据层隔离方面,你们主要做了哪些工作呢?

Bilicen:对数据层隔离,首先要对原 DB 类文件进行改进,同时系统的逻辑层不会出现直接操作数据库的
SQL 语句。举例来说:当你需要在 Discuz!
X2.5 方舟上装载一批集装箱货时,你可以将它们全部放在甲板上,但不能把它们放在方舟的船舱、驾驶室等部位,以保障方舟的安全驾驶与稳定航行。

以代码编写为例,之前的代码是这样写的:

$rushresult = DB::fetch_first("SELECT * FROM ".DB::table('forum_threadrush')." WHERE tid='$_G[tid]'");

现在,在新的架构体系下,代码实现已经如下:

$rushresult = C::t('forum_threadrush')->fetch($_G['tid']);

可以看出,数据读写已经完全封装,在程序的业务逻辑层不会出现直接操作数据库的 SQL 语句。感兴趣的读者,也可以参考 forum_viewthread.php 文件的编写代码对比。

《站长》:数据读写封装对站长有哪些好处呢?

Bilicen:好处是显而易见的,数据层隔离 (附 2) 使得 Discuz!
X2.5 系统更加安全、拓展性更强、负载能力更高,也为内存级缓存层增加和数据库分布式部署奠定了基础,第三方插件不必再跟随者系统架构的升级而升级。这
就像文章开头所说的,从货轮升级为诺亚方舟,不仅更加稳定与安全,并且支持各种各样的功能插件,能满足更多站长多样化需求。

《站长》:谢谢 Bilicen 。下一期请为我们讲解下 Discuz! 在分服务器部署方面的创新。

附 1:关于 class_core.php 入口文件以及 function_core.php 减肥之术:

Class_core.php 是入口启动文件,主要实现了以下功能:

1 、注册 autoload 方法和异常处理方法;

2 、 C::t 方法的实现;

3 、 memory 的初始化;

4 、创建 discuz_application 实例 (discuz_application 是原来 Discuz! X2 的 discuz_core);

5 、简写类的映射:

class C extends core {}

class DB extends discuz_database {}

function_core.php 是系统的核心函数库文件,随着系统功能的丰富,函数库越来越大,慢慢地变成了系统快速启动的负担,为此我们将
function_core 中的函数按功能拆分到不同的类文件中,实现程序的按需加载;原有函数名保留不变,做相应类静态方法的映射,兼容产品和插件的用
法。

具体做法是在 source/class 目录增加两个目录,helper 和 lib source/class/helper 目录中的文件为函数的分类
集合,类的静态方法,可直接使用不用实例化 source/class/lib 目录中的文件为工具类的集合类文件,使用时需实例化。

附 2:数据层隔离:

1 、 addslashes 的处理

insert(),update(),delete() 方法对传入其的数组形式的参数进行安全处理:intval 或 addslashes,字符串形式的参数将不处理,请注意;

2 、新添加的方法

fetch_all($sql),order(), limit(),field() 等方法,其中 fetch_all 方法以数组方式返回查询多条记录数据,且可以设置数据的 KEY 值使用某字段值;

3 、增加 SQL 语句 format 的支持

例:查询 10 个用户 uid 大于 100 的用户数据,以 uid 为返回结果数组的 key

$arr = DB::fetch_all(『SELECT * FROM %t WHERE uid>%d LIMIT %d』, array(『common_member』, 『100』, 『10』), 『uid』);

支持的 fomat 有:

%t

DB::table()

%d

intval()

%s

Addslashes()

%n

id IN (1,2,3)

%f

sprintf(『%F』, $var)

%i

直接使用不进行处理

4 、返回值的处理

在非 UNBUFFERED 的情况下:

INSERT SQL 语句返回 insert_id()

UPDATE 和 DELETE SQL 语句返回 affected_rows()