编者按: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()