Contenu connexe
Similaire à Discuz技术交流 (20)
Discuz技术交流
- 1. Discuz!技术交流
浪湾<langwanluo@comsenz.com>
http://www.phpchina.com
- 3. 大家关心的问题
• 论坛性能优化
• 缓存
• Discuz!速度、稳定性、功能。
• 6.0及下版本的发布时间。
• 代码规范、团队管理以及大型项目应对。
• 二次开发、整合、扩展能力、用户系统。
• 数据库设计。
• 详细的技术分析。
- 5. • 骨干构架稳定,版本挑剔性底。
• fopen mysql_query array md5 time explode list strlen PHP3
• print_r var_export PHP4.2.0以下
• 错误处理简单,没有复杂的错误信息。
• 语法近于C与Java之间,并顺装了Linxu下的不少Shell。
• strlen printf strcmp / system chmod touch
• PHP5的类设计更像JAVA。
• 有广泛自由的设计空间与现成构架。
• 平行的函数构架。
• pear开源网站
• 嵌入式PHP也是不错的选择。
• 路由器 机顶盒 KTV 酒店系统
• 开发环境舒适。
• 记事本
• Zend Studio 类比微软和Sun来说还是精简的。
• UE, SQLyog(database)
• 应用能力适中,结合性强。
• 缺点,缺乏线程机制,内存控制力,编译不够完美。
• 小李飞刀闻名再人而非刀。
- 8. 六、 我们认为某些基本价值是Discuz!永远坚持的。这包括:
――自由。人们不分男女,有权在不违法、不影响他人的情况下选择自己的网上社
区生活。社区建设者有权在最大化维护社区网民的利益下,以民为本的自由选择各
类经营项目!包括对社区技术系统平台的自由替换和选择权利!
――平等。社区经营者不分信仰、国别、年龄、性别及背景,皆享有免费使用
Discuz!产品的平等权利!
――安全。与网站或网页不同,社区内的每个文字和记录都是由网民亲自创造的,
社区上承载的每个ID都有着丰富感情的现实个体。正因为如此,Discuz!将确保能
永远提供网上最安全的社区技术平台和解决方案。
――跨平台。无论社区经营者选择哪一种技术平台系统,Unix、Windows或Linux,
皆有选择Discuz!的自由,犹如好客的主人,尊重五湖四海宾客的信仰一样,
Discuz!过去、现在、直至将来,永远都不会放弃这种跨平台的选择自由!
――技术性能与效率。与所有的软件产品一样,追求产品本身的卓越质量都是无可
厚非的。但是,作为一个社区软件系统,我们追求高性能高效率还有另外一层含
义,那就是,尽量帮助我们的社区建设者最大化降低硬件成本、最大可能地减少带
宽资源的投资!
――优质服务。Discuz!一直坚持给社区网民、社区建设者提供最优质的产品和服
务为己任。我们深知,社区的服务需求万万千,Discuz!谦虚谨慎,不断开发各类
个性化服务。
- 9. 七、 为了把这些价值和原则变为行动,兹将我们特别重视的一些关键目标从2006
年起,逐步展示于众。
八、 我们将竭尽全力,在保证我们能够生存并持续发展的前提下,对Discuz!社
区软件产品实施免费。在目前数万免费用户的基础上,将此项福利惠及更多的社区建
设者。
九、 因此,我们决心:
--永远为免费版用户提供最全面的产品功能。
――永远向免费版用户提供稳定、长期的可升级支持。
――永远让免费版用户享受到基本的网上社区技术支持服务。
――永远支持中小网站、个人网站,尤其鼓励基于草根的社区应用创新,我们将在免
费产品中不断开发新功能,满足这些灵感的技术实现。
十、 我们希望Discuz!产品永远永远免费下去,如果非要在她前面加上一个期限,
我们希望将是一万年。
- 11. Discuz! 特征(一)
• 版本2
• 独有先进的编译模板内核,全部模板采用文件存储,前台界面完全使用语言包构件语言元素
• 全面支持多模板,多语言和分论坛间设定不同的模板,风格和语言
• 自建 SMTP 模块,支持 ESMTP 验证,并提供三种可选方式发送邮
• 版本3
• 新增带缓存的高效率首页新帖调用功能
• Discuz! 3.10 在论坛易用性,人性化方面做了重大改进,同时安全级别也明显提升
• 版本4
• 新增整合的论坛 Blog 系统,最大限度的实现资源多层次利用并可设定哪些用户有权使用本功能
• 增加广告管理系统,可实现表格自动排布、分版及随机展现
• 新增 WAP 功能,可实现登录、看帖、发帖、回帖、收发短消息等功能
• 彻底革命的积分体系
• 新增 Cron(计划任务) 机制,并提供自定义计划任务接口
• 新增URL静态化选项,可将常见URL翻译为静态形式(伪html),使论坛更容让搜索引擎收录
• 优化 mysql 模块,提高对Mysql各版本的兼容性,完美支持 Mysql 5.0新增数据库字符集的设置
• 新增附件点击数延迟更新功能
• 增加系统数据加密方法
- 12. Discuz! 特征(二)
• 版本5
• 融入更多 Web 2.0 元素,新增多样化论坛主题功能,最多可扩充至 256 种主题类型
• 新增 My(我的 ...)功能模块更加关注论坛用户的使用体验和成长经历,用户可以随时查阅发
表的主题、回复、交易、活动、收藏 ...
• 新增所见即所得编辑器,可兼容大部分浏览器,支持自定义 Discuz! 代码快捷输入按钮
• 新增 js 菜单支持,为用户自定制 js 菜单留有接口
• 优化计划任务,避免论坛并发人数过大,任务重复执行。
• 优化搜索引擎支持,调整论坛网页 title 显示顺序,提高搜索引擎收录几率
• 新增 MiniSpace 功能,充分关注会员的成长历程和个性展示
• 增强 WAP 系统,新增WAP注册功能在手机设备兼容性能上大为提高,重新设计的操作界面更
符合 WAP 标准和手机用户的使用习惯
• 新增 左右分栏功能,显示风格与论坛自动融合,扩展方便。支持后台开关和会员开关
• 首创 GIF 动画验证码支持,提高灌水机识别难度
• 新增 论坛策略方案系统
• 新增 公告类型-公共短消息,可强制提醒用户阅读某些重要内容。公共短消息无论一次发给多
少用户,均为一条数据存储,不会占用过多资源
• 广告位全新布局 提升论坛盈利空间
• 加强论坛安全防御措施,让站长更加安心
• 新增 远程附件上传、管理功能
- 13. Discuz! 特征 (三)
• 版本6
• 全面优化论坛显示模板,大幅度提升页面显示速度,为您带来极速浏览体验
• 论坛页面采用 XHTML 标准以及结构化 CSS 设计,让风格设计更加随心所欲
• 内置 6 套精心设计的炫酷风格,让论坛更具个性风采,可符合大部分站点需求
• 新增 Insenz 社区系列营销服务,为广大站长提供高质量的、与社区定位相匹配的广告和稳定的
收益
• 采用 Ajax 技术让管理人员通过双击帖子标题或者帖子内容进行进行标题和内容的编辑
• 采用 Ajax 技术完成阅读短消息和发送短消息
• 新增 标签(Tag)功能,主动式信息分类让论坛主题相互链接,提高站点 PV
• 新增 辩论主题功能,会员可发起辩论主题,实时显示辩论情况
• 全新 论坛交易体系,使论坛可以迅速搭建成 C2C、B2C 电子交易平台
• 新增 个性化分类信息主题发布系统,彻底打破论坛传统的(主题+内容)模式。
• 新增 论坛板块 SEO 设置,各板块可分别设置关键词,更利于搜索引擎收录
• 新增 发布视频功能
• 增强 CC 防御体系,调整 CC 防御策略,减少在防御功能开启后对正常用户浏览的干
- 15. 用户驱动开发 使用基数不断攀升去年30万,今年40万
- 19. if(in_array($action, array('moderate', 'delete', 'move', 'highlight', 'type',
if(!empty($url_forward)) {
echo "<meta httpequiv=refresh content="0;URL=$url_forward">";exit;
}
7. SQL语句中的=、<>、>、<、+等操作符前后不允许有空格。
groupuid WHERE gid='$gid' AND uid='$discuz_uid' AND flag>1", 'SILENT');
8. 段前段后留白
} elseif($action == 'split') {
if(!submitcheck('splitsubmit')) {
require_once DISCUZ_ROOT.'./include/discuzcode.func.php';
...
include template('topicadmin_split');
} else {
9. 简单if的替代写法 $page > $totalpage && $page = $totalpage;
- 22. 尽可能减少实时性操作
函数定义 表 判定ID 更新列 缓存
function updateviews($table, $idcol, $viewscol, $logfile) {
global $db, $tablepre;
$viewlog = $viewarray = array();
if(@$viewlog = file($logfile = DISCUZ_ROOT.$logfile)) {
@unlink($logfile);
$viewlog = array_count_values($viewlog);
foreach($viewlog as $id => $views) {
$viewarray[$views] .= ($id > 0) ? ','.intval($id) : '';
}
foreach($viewarray as $views => $ids) {
$db>query("UPDATE LOW_PRIORITY $tablepre$table
SET $viewscol=$viewscol+'$views' WHERE $idcol IN (0$ids)"
, 'UNBUFFERED');
}
}
}
- 24. 基本环境
1. showmessage()的使用
if(!$member = $db>fetch_array($query)) {
showmessage('member_nonexistence');
识别标签
}if(!$allowviewpro) {
showmessage('group_nopermission', NULL, 'NOPERM');
}
message.lang.php 文件中有定义
'member_nonexistence' => '指定的用户不存在或已被删除,请返回。',
都有返回上一页链接
信息 是否跳转 扩展属性
function showmessage($message, $url_forward = '', $extra = '') {
<!{if $url_forward}>
<p><a href="$url_forward">{lang message_forward}</a></p>
<!{elseif stristr($show_message, '{lang return}')}>
<p><a href="javascript:history.back()">{lang message_go_back}</a></p>
<!{/if}>
- 29. mysql_insert_id() 解决办法
function insert_id() {
return ($id = mysql_insert_id($this>link)) >= 0 ? $id :
$this>result($this>query("SELECT last_insert_id()"), 0);
}
后者是按照字符串返回的。
8. 数据库安全 要考虑BIG5冲码问题,以及在查询中增加
if($dbcharset) {
@mysql_query("SET character_set_connection=$dbcharset
, character_set_results=$dbcharset
, character_set_client=binary"
, $this>link);
}
- 31. 协议安全性
由于HTTP、FTP协议的老弱,协议封装不严格,导致的因换行为主的隐患。
1. IP地址的漏洞
preg_match("/[d.]{7,15}/", $onlineip, $onlineipmatches);
$onlineip = $onlineipmatches[0] ? $onlineipmatches[0] : 'unknown';
unset($onlineipmatches);
2. FTP换行漏洞
function dftp_get($ftp_stream, $local_file, $remote_file, $mode, $resumepos = 0) {
$remote_file = wipespecial($remote_file);
$local_file = wipespecial($local_file);
$mode = intval($mode);
$resumepos = intval($resumepos);
return @ftp_get($ftp_stream, $local_file, $remote_file, $mode, $resumepos);
}
function wipespecial($str) {
return str_replace(array('..', "n", "r"), array('', '', ''), $str);
}
- 32. 3. HTTP协议的换行漏洞
function dheader($string, $replace = true, $http_response_code = 0) {
$string = str_replace(array("r", "n"), array('', ''), $string);
if(empty($http_response_code) || PHP_VERSION < '4.3' ) {
@header($string, $replace);
} else {
@header($string, $replace, $http_response_code);
}
if(preg_match('/^s*location:/is', $string)) {
exit();
}
}
- 34. 效率和性能
1. 使用内存表改善缓存性数据。
cdb_sessions CREATE TABLE `cdb_sessions` (
`sid` char(6) character set ...
...
) ENGINE=MEMORY DEFAULT CHARSET=gbk
2. 使用以下手段解决limit变慢的问题
* 缓存查询结果
* 限制翻页的最大上限,例如PAGE * MAXROW = TOTAL,100 * 20 = 2000条以内其实足够了,百度、新浪、
google也是如此。
* 增加最大上限查询时间。例如一年内或者按年归档数据。
* 使用其它数据源做搜索,例如备份数据联合lucene等。
* 作为小系统限制为主,索引为辅、技巧其次。
* 当每页行数在30以上,可以仅使用 where id < B and id > A , B – A = 30来罗列。
- 35. * 可以判定翻页条件 例如 CUR_PAGE > TOTAL_PAGE / 2,改变order by的升降
$totalpage = ceil(($thread['replies'] + 1) / $ppp);
$page > $totalpage && $page = $totalpage;
$pagebydesc = $page > 50 && $page > ($totalpage / 2) ? TRUE : FALSE;
if($pagebydesc) {
$firstpagesize = ($thread['replies'] + 1) % $ppp;
$ppp2 = $page == $totalpage && $firstpagesize ? $firstpagesize : $ppp;
$realpage = $totalpage $page + 1;
$start_limit = max(0, ($realpage 2) * $ppp + $firstpagesize);
$numpost = ($page 1) * $ppp;
$pageadd = "ORDER BY dateline DESC LIMIT $start_limit, $ppp2";
} else {
$start_limit = $numpost = ($page 1) * $ppp;
if($start_limit > $thread['replies']) {
$start_limit = $numpost = 0;
$page = 1;
}
$pageadd = "ORDER BY dateline LIMIT $start_limit, $ppp";
}
- 36. 2. 使用explain分析效率。
* 如果rows字段过大例如rows = 100000 需要缩小where语句的条件或更换where条件的顺序。
* 如果Extra信息里包含Using filesort并且rows也很大需要增大sort_buffer_size
SET GLOBAL sort_buffer_size=value;
出现using filesort需要对索引重新调整,还是可以消除filesort的
* Using temporary创建临时表,需要优化group by
3. 使用show processlist;
mysql> show processlist;
+++++++++
| Id | User | Host | db | Command | Time | State | Info |
+++++++++
| 1 | root | localhost:1032 | discuz6 | Sleep | 45 | | NULL |
| 2 | root | localhost:1033 | NULL | Sleep | 78 |Locked | select * from cdb |
| 5 | root | localhost:1036 | NULL | Query | 0 | NULL | show processlist |
+++++++++
3 rows in set (0.00 sec)
* 如果State=Locked就是锁表,如果Time时间过长,超过20秒,就会带着下面一系列的SQL全部锁死。
- 44. 4. 获取缓存信息,并调用缓存
if($threadcachemark < $forum['threadcaches']) {
$threadcache = getcacheinfo($tid);
if($timestamp $threadcache['filemtime'] > $cachethreadlife) {
@unlink($threadcache['filename']);
define('CACHE_FILE', $threadcache['filename']);
$styleid = $_DCACHE['settings']['styleid'];
@include DISCUZ_ROOT.'./forumdata/cache/style_'.$styleid.'.php';
} else {
readfile($threadcache['filename']);
- 45. 5. getcacheinfo()函数
function getcacheinfo($tid) {
global $timestamp, $cachethreadlife, $cachethreaddir;
$tid = intval($tid);
$cachethreaddir2 = DISCUZ_ROOT.'./'.$cachethreaddir;
$cache = array('filemtime' => 0, 'filename' => '');
$tidmd5 = substr(md5($tid), 3);
$fulldir = $cachethreaddir2.'/'.$tidmd5[0].'/'.$tidmd5[1].'/'.$tidmd5[2].'/';
$cache['filename'] = $fulldir.$tid.'.htm';
if(file_exists($cache['filename'])) {
$cache['filemtime'] = filemtime($cache['filename']);
} else {
if(!is_dir($fulldir)) {
for($i=0; $i<3; $i++) {
$cachethreaddir2 .= '/'.$tidmd5{$i};
if(!is_dir($cachethreaddir2)) {
@mkdir($cachethreaddir2, 0777);
@touch($cachethreaddir2.'/index.htm');
}
}
}
}
return $cache;
}
取md5(tid)的前三位,作为三层目录结构。得到缓存的路径及创建时间,存放到数组中返回。
- 51. 项目改造、二次开发
1. 开启帖子缓存功能,大幅减少SQL查询。
2. 把部分常态缓存放到/dev/shm/的共享缓存里,减少IO数量。
3. 使用F5均衡Web负载。
4. 使用squid技术做前端静态缓存。
5. 独立附件服务器,设置独立的域名。
6. 对磁盘做Raid5或Raid10。
7. 使用MySQL商业版本的集群技术。
8. 对大表分表存归档。
9. 使用lucene等分离搜索服务器。
10. 对不同版块使用不同服务器不同域名。搜索不可以跨板块。
11. 处理好SSO或者通行证系统。
12. 尝试使用Zeus、lighttpd服务器来替代apache。
13. 买CDN吧。
14. 从数据库备份中搜索或做统计信息,避免由于搜索带来的锁表,引起的数据库错误。
15. 使用系统Cron或AT来代替PHP脚本的计划任务。
16. 适当增加一些守护进程或系统级计划任务来缓存或交换数据。
17. 系统级的对web服务器、Apache服务器进行缓存调优。
18. 对不良来源的请求进行屏蔽。
19. 适当增加索引,减慢插入,加速查询。