Discuz! X2.5新版架构优化主要针对以下6个方面:一.程序底层架构的改进;二.用户输入数据的处理;三.数据库DB层的改进;四.内存级缓存层的优化;五.多服务器分库分布式部署;六.主要性能瓶颈点的优化。 
 
程序底层架构 
 
• 要求PHP版本大于5.1,抛弃了对PHP4的支持 
• 大量使用了面向对象编程(OOP) 
• 实现了程序运程过程中按需加载,按需加载主要是针对类文件 
• 对目录名、文件名和类名的要求 
 
类文件存在在/source/class 目录中,类名和文件名相同,一个类一个文件 类名以下划线(_)分隔,第一个下划线之前部分为目录名,没有下划线的类名直接放/source/class/目录下。 
 
产品中个别特殊类由于历史原因无法实现自动加载,需手动处理 include或require 
 
• class_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.php是系统的核心函数库文件,随着系统功能的丰富,函数库越来越大,慢慢地变成了系统快速启动的负担,为此我们将function_core中的函数按功能拆分到不同的类文件中,实现程序的按需加载; 原有函数名保留不变,做相应类静态方法的映射,兼容产品和插件的用法。 
 
具体做法是在source/class目录增加两个目录,helper和lib source/class/helper目录中的文件为函数的分类集合,类的静态方法,可直接使用不用实例化 source/class/lib目录中的文件为工具类的集合类文件,使用时需实例化 
 
用户输入数据的处理 
 
Discus! X2.5之前版本对$_GET和$_POST的值默认是进行addslashes处理,函数在使用此值时信任外部数据的安全性,但这样处理的弊端是容易生产二次注射的漏洞,为了防止此类漏洞的产生,函数必须不信任任何数据外部数据的安全性,为此我们做了以下的处理增强系统安全: 
 
    $_GET和$_POST的值默认不做addslashes处理; 
    $_GET为$_GET和$_POST数组的合并,代码中统一使用$_GET取值; 
    $_G['gp_xx']的写法默认不再支持,config.php中有兼容开关; 
  $_config['input']['compatible'] = 1;// $_GET|$_POST的兼容处理,0为关闭, 
         1为开启;开启后即可使用$_G['gp_xx'](xx为变量名,$_GET和$_POST集合的所有变量 名),值为已经addslashes()处理过,兼容插件; 
 
数据库DB层 
 
• 原DB类的改进 
 
Discuz! X2.5新版对数据库DB层进行了功能和安全方面的加强: 
 
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 in IN (1,2,3)
 
 - %f sprintf('%f', $var)
 
 - %i 直接使用不进行处理
 
  复制代码 
4、返回值的处理 
 
在非UNBUFFERED的情况下: 
INSERT SQL语句返回insert_id() 
UPDATE和DELETE SQL语句返回affected_rows() 
 
• 新增数据层:数据层的规范和约定 
    • 一个数据表一个class文件,以table_加上不带前缀的表名命名,尽量不操作其它表; 
例:source/class/table/table_common_member.php  
     • 不能使用$_G、$POST、$GET等全局变量; 
    • 关联查询(JOIN)尽量拆分为单条查询,不能拆分的放入主表的类中; 
    • 方法名以下划线分隔,全部为小写,全部为单数,直接返回结果,保留关键字: 
      on、get、set, 方法参数不能以数组的形式传入,数据可以; 
    • 除数据表文件以外,其它文件禁止出现SQL语句; 
    • 查询结果返回一行记录方法名使用fetch开头,返回多行记录方法名使用fetch_all 
      开头,查询中使用SQL语句count函数返回一个数值的使用count开头; 
    • 方法名中by后面的是以下划线(_)分隔的表字段名,不要使用复数型,例如: 
      fetch_all_by_uid()而不是fetch_all_by_uids(); 
 
    • 方法名需去掉表名,如:common_member表类方法 
      fetch_member_by_username应命名为fetch_by_username; 
    • 数据表类继承discuz_table基类,基类实现CURD操作,fetch方法实现了根据一个主键 值得到一行记录、fetch_all方法实现了根据一组主键值得到多行记录(二维数据,主  键值为 key)、count方法返回了表的总记录数据; 
    • 如果表是无主键或是关联主键,则基类中的CURD将不能使用,需自己在相应的表类中实现, 同时将$this->_pk设置为空; 
    • DB层封装的函数实现了addslashes,个别直接写sql语句的需主意addslashes; 
    • 使用C::t('tablename')->method();调用; 
    • C::t插件调用方式- 表名:mytablename 
 
 - 目录:source/plugin/mypluginid/table/table_mytablename.php 
 
 - 类名:table_mytablename 
 
 - 用法:C::t('#mypluginid#mytablename')->method()
 
  复制代码 
 
 
相关阅读: 
1、Discuz!的插件流程、文件命名规范和class_core.php 
2、Discuz! 的插件之特殊主题脚本格式 
3、Discuz 任务、道具、任务和验证类插件制作 
4、Discuz 插件的安装、卸载和升级XML制作方法 
5、Discuz插件程序和模板语言包制作方法 
 |   
 
上一篇: Discuz 的插件流程、文件命名规范和class_core.php下一篇: xweibo标准版升级到OAuth 2.0接口方法说明文档(patch_20120911_oauth2.0) 
 
 |