发布时间:2025-12-09 16:41:31 浏览次数:4
转
2014年03月07日 11:51:34 囧 阅读数:3604 标签: 源代码代码分析discuz 收起
个人分类: PHP
第一个文件当然是分析./include/common.inc.php这个文件,这个是Discuz的核心中的核心,基本上每次操作都include到了这个文件,下面就分七段来分析这个文件:
Section One:
QUOTE:
CODE:
//定义PHP一些环境QUOTE:
CODE:
require_once DISCUZ_ROOT.'./include/global.func.php';把include/global.inc.php引用进来,这个文件是Discuz的核心函数文件,包含了Discuz用到的很多通用的函数,可以说它就是一个大的通用函数库。CODE:
define('ISROBOT', getrobot());CODE:
define('MAGIC_QUOTES_GPC', get_magic_quotes_gpc());CODE:
$charset = $dbcharset = $forumfounders = $metakeywords = $extrahead = '';CODE:
unset($prelength, $_request, $_key, $_value);CODE:
require_once DISCUZ_ROOT.'./include/db_'.$database.'.class.php';QUOTE:
CODE:
preg_match("/[/d/.]{7,15}/", $onlineip, $onlineipmatches);CODE:
$cachelost = (@include DISCUZ_ROOT.'./forumdata/cache/cache_settings.php') ? '' : 'settings';CODE:
if($gzipcompress && function_exists('ob_gzhandler') && CURSCRIPT != 'wap') {CODE:
if(!empty($loadctrl) && substr(PHP_OS, 0, 3) != 'WIN') {CODE:
if(defined('CURSCRIPT') && in_array(CURSCRIPT, array('index', 'forumdisplay', 'viewthread', 'post', 'blog', 'pm', 'topicadmin', 'register', 'archiver'))) {
论坛模式 推荐 收藏 分享给好友 推荐到圈子 管理
TAG:
笨才 发布于2007-05-28 11:19:15
Section Four:
QUOTE:
CODE:
$db = new dbstuff;CODE:
$sid = daddslashes(($transsidstatus || (defined('CURSCRIPT') && CURSCRIPT == 'wap'))&& (isset($_GET['sid']) || isset($_POST['sid'])) ?CODE:
$discuz_auth_key = md5($_DCACHE['settings']['authkey'].$_SERVER['HTTP_USER_AGENT']);设置一个$discuz_auth_key,md5加密。。CODE:
if(isset($_DCOOKIE['auth']) && $_DCOOKIE['auth']) {Section Five:
QUOTE:
CODE:
$newpm = $newpmexists = $sessionexists = $seccode = $bloguid = 0;//初始化变量CODE:
if(!$sessionexists) {CODE:
if(ipbanned($onlineip)) $_DSESSION['ipbanned'] = 1;CODE:
$membertablefields = '';CODE:
$accessadd1 = $accessadd2 = $modadd1 = $modadd2 = '';CODE:
define('FORMHASH', formhash());CODE:
$rsshead = $navtitle = $navigation = '';CODE:
if($passport_status && ($passport_status != 'shopex' || !$passport_shopex)) {CODE:
if($discuz_uid && $_DSESSION) {CODE:
if(!in_array($adminid, array(1, 2, 3))) {CODE:
$forum = array();CODE:
$styleid = intval(!empty($_GET['styleid']) ? $_GET['styleid'] :CODE:
if($cachelost) {CODE:
if(!defined('CURSCRIPT') || CURSCRIPT != 'wap') {CODE:
if($cronnextrun && $cronnextrun <= $timestamp) {CODE:
if(isset($plugins['include']) && is_array($plugins['include'])) {CODE:
if((!empty($_DCACHE['advs']) || $globaladvs || $redirectadvs) && !defined('IN_ADMINCP')) {CODE:
if(isset($allowvisit) && $allowvisit == 0 && !(defined('CURSCRIPT') && CURSCRIPT == 'member' && $action == 'groupexpiry')) {CODE:
if((!empty($fromuid) || !empty($fromuser)) && ($creditspolicy['promotion_visit'] || $creditspolicy['promotion_register'])) {CODE:
$rssauth = $rssstatus && $discuz_uid ? rawurlencode(authcode("$discuz_uid/t".($fid ? $fid : '')."/t".substr(md5($discuz_pw.$discuz_secques), 0, 8), 'ENCODE', md5($_DCACHE['settings']['authkey']))) : '0';Rss检查CODE:
//同样,防止非法引用用的。
if(!defined('IN_DISCUZ')) {
exit('Access Denied');
}
CODE:
/**
* 这个函数看着很长,其实要实现的功能很少,就是通过ip地址返回一个对应的地理位置
* @para string $ip //给定的ip,要符合点分十进制
*
* @return string
*/
function convertip($ip) {
if(!preg_match("/^/d{1,3}/./d{1,3}/./d{1,3}/./d{1,3}$/", $ip)) {
return '';
}
if($fd = @fopen(DISCUZ_ROOT.'./ipdata/wry.dat', 'rb')) {
$ip = explode('.', $ip);
$ipNum = $ip[0] * 16777216 + $ip[1] * 65536 + $ip[2] * 256 + $ip[3];
$DataBegin = fread($fd, 4);
$DataEnd = fread($fd, 4);
$ipbegin = implode('', unpack('L', $DataBegin));
if($ipbegin < 0) $ipbegin += pow(2, 32);
$ipend = implode('', unpack('L', $DataEnd));
if($ipend < 0) $ipend += pow(2, 32);
$ipAllNum = ($ipend - $ipbegin) / 7 + 1;
$BeginNum = 0;
$EndNum = $ipAllNum;
while($ip1num > $ipNum || $ip2num < $ipNum) {
$Middle= intval(($EndNum + $BeginNum) / 2);
fseek($fd, $ipbegin + 7 * $Middle);
$ipData1 = fread($fd, 4);
if(strlen($ipData1) < 4) {
fclose($fd);
return '- System Error';
}
$ip1num = implode('', unpack('L', $ipData1));
if($ip1num < 0) $ip1num += pow(2, 32);
if($ip1num > $ipNum) {
$EndNum = $Middle;
continue;
}
$DataSeek = fread($fd, 3);
if(strlen($DataSeek) < 3) {
fclose($fd);
return '- System Error';
}
$DataSeek = implode('', unpack('L', $DataSeek.chr(0)));
fseek($fd, $DataSeek);
$ipData2 = fread($fd, 4);
if(strlen($ipData2) < 4) {
fclose($fd);
return '- System Error';
}
$ip2num = implode('', unpack('L', $ipData2));
if($ip2num < 0) $ip2num += pow(2, 32);
if($ip2num < $ipNum) {
if($Middle == $BeginNum) {
fclose($fd);
return '- Unknown';
}
$BeginNum = $Middle;
}
}
$ipFlag = fread($fd, 1);
if($ipFlag == chr(1)) {
$ipSeek = fread($fd, 3);
if(strlen($ipSeek) < 3) {
fclose($fd);
return '- System Error';
}
$ipSeek = implode('', unpack('L', $ipSeek.chr(0)));
fseek($fd, $ipSeek);
$ipFlag = fread($fd, 1);
}
if($ipFlag == chr(2)) {
$AddrSeek = fread($fd, 3);
if(strlen($AddrSeek) < 3) {
fclose($fd);
return '- System Error';
}
$ipFlag = fread($fd, 1);
if($ipFlag == chr(2)) {
$AddrSeek2 = fread($fd, 3);
if(strlen($AddrSeek2) < 3) {
fclose($fd);
return '- System Error';
}
$AddrSeek2 = implode('', unpack('L', $AddrSeek2.chr(0)));
fseek($fd, $AddrSeek2);
} else {
fseek($fd, -1, SEEK_CUR);
}
while(($char = fread($fd, 1)) != chr(0))
$ipAddr2 .= $char;
$AddrSeek = implode('', unpack('L', $AddrSeek.chr(0)));
fseek($fd, $AddrSeek);
while(($char = fread($fd, 1)) != chr(0))
$ipAddr1 .= $char;
} else {
fseek($fd, -1, SEEK_CUR);
while(($char = fread($fd, 1)) != chr(0))
$ipAddr1 .= $char;
$ipFlag = fread($fd, 1);
if($ipFlag == chr(2)) {
$AddrSeek2 = fread($fd, 3);
if(strlen($AddrSeek2) < 3) {
fclose($fd);
return '- System Error';
}
$AddrSeek2 = implode('', unpack('L', $AddrSeek2.chr(0)));
fseek($fd, $AddrSeek2);
} else {
fseek($fd, -1, SEEK_CUR);
}
while(($char = fread($fd, 1)) != chr(0))
$ipAddr2 .= $char;
}
fclose($fd);
if(preg_match('/http/i', $ipAddr2)) {
$ipAddr2 = '';
}
$ipaddr = "$ipAddr1 $ipAddr2";
$ipaddr = preg_replace('/CZ88/.NET/is', '', $ipaddr);
$ipaddr = preg_replace('/^/s*/is', '', $ipaddr);
$ipaddr = preg_replace('//s*$/is', '', $ipaddr);
if(preg_match('/http/i', $ipaddr) || $ipaddr == '') {
$ipaddr = '- Unknown';
}
return '- '.$ipaddr;
} else {
$datadir = DISCUZ_ROOT.'./ipdata/';
$ip_detail = explode('.', $ip);
if(file_exists($datadir.$ip_detail[0].'.txt')) {
$ip_fdata = @fopen($datadir.$ip_detail[0].'.txt', 'r');
} else {
if(!($ip_fdata = @fopen($datadir.'0.txt', 'r'))) {
return '- Invalid IP data file';
}
}
for($i = 0; $i <= 3; $i++) {
$ip_detail[$i] = sprintf('%03d', $ip_detail[$i]);
}
$ip = join('.', $ip_detail);
do {
$ip_data = fgets($ip_fdata, 200);
$ip_data_detail = explode('|', $ip_data);
if($ip >= $ip_data_detail[0] && $ip <= $ip_data_detail[1]) {
fclose($ip_fdata);
return '- '.$ip_data_detail[2].$ip_data_detail[3];
}
} while(!feof($ip_fdata));
fclose($ip_fdata);
return '- UNKNOWN';
}
}
CODE:
/**
* 目前发现这个函数在两个地方用到,search.php和digest.php,这个函数的用处是把从数据库中得到的帖子处理一下,然后给前端显示。
* @para array $thread //从数据库中取出的帖子原始数据
*
* @return array
*/
function procthread($thread) {
global $dateformat, $timeformat, $timeoffset, $ppp, $colorarray;
if(empty($colorarray)) {
$colorarray = array('', 'red', 'orange', 'yellow', 'green', 'cyan', 'blue', 'purple', 'gray');
}
$thread['forumname'] = $GLOBALS['_DCACHE']['forums'][$thread['fid']]['name'];
$thread['dateline'] = gmdate($dateformat, $thread['dateline'] + $timeoffset * 3600);
$thread['lastpost'] = gmdate("$dateformat $timeformat", $thread['lastpost'] + $timeoffset * 3600);
$thread['lastposterenc'] = rawurlencode($thread['lastposter']);
if($thread['replies'] > $thread['views']) {
$thread['views'] = $thread['replies'];
}
$postsnum = $thread['replies'] + 1;
$pagelinks = '';
if($postsnum > $ppp) {
$posts = $postsnum;
$topicpages = ceil($posts / $ppp);
for($i = 1; $i <= $topicpages; $i++) {
$pagelinks .= '<a href="viewthread.php?tid='.$thread['tid'].'&page='.$i.'" target="_blank">'.$i.'</a> ';
if($i == 6) {
$i = $topicpages + 1;
}
}
if($topicpages > 6) {
$pagelinks .= ' .. <a href="viewthread.php?tid='.$thread['tid'].'&page='.$topicpages.'" target="_blank">'.$topicpages.'</a> ';
}
$thread['multipage'] = ' ( <img src="'.IMGDIR.'/multipage.gif" class="absmiddle" border="0" alt="" /> '.$pagelinks.')';
} else {
$thread['multipage'] = '';
}
if($thread['highlight']) {
$string = sprintf('%02d', $thread['highlight']);
$stylestr = sprintf('%03b', $string[0]);
$thread['highlight'] = 'style="';
$thread['highlight'] .= $stylestr[0] ? 'font-weight: bold;' : '';
$thread['highlight'] .= $stylestr[1] ? 'font-style: italic;' : '';
$thread['highlight'] .= $stylestr[2] ? 'text-decoration: underline;' : '';
$thread['highlight'] .= $string[1] ? 'color: '.$colorarray[$string[1]] : '';
$thread['highlight'] .= '"';
} else {
$thread['highlight'] = '';
}
if($thread['attachment']) {
require_once DISCUZ_ROOT.'./include/attachment.func.php';
$thread['attachment'] = attachtype($thread['attachment']).' ';
} else {
$thread['attachment'] = '';
}
return $thread;
}
CODE:
/**
* 用来更新点击数的
* @para string $table //用来更新的数据表
* @para string $idcol //用来更新的数据的id
* @para string $viewscol //用来更新的列
* @para string $logfile //日志文件,点击是写入日志的
*/
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 $tablepre$table SET $viewscol=$viewscol+$views WHERE $idcol IN (0$ids)", 'UNBUFFERED');
}
}
}
CODE:
/**
* 给版主的工作写入日志的
* @para array $thread //对哪个帖子的操作
* @para string $action //进行的什么操作
*
*/
function modlog($thread, $action) {
global $discuz_user, $adminid, $onlineip, $timestamp, $forum, $reason;
writelog('modslog', dhtmlspecialchars("$timestamp/t$discuz_user/t$adminid/t$onlineip/t$forum[fid]/t$forum[name]/t$thread[tid]/t$thread[subject]/t$action/t$reason"));
}
CODE:
/**
* 检查是不是写了理由
*
*/
function checkreasonpm() {
global $reason;
$reason = trim(strip_tags($reason));
if(($GLOBALS['reasonpm'] == 1 || $GLOBALS['reasonpm'] == 3) && !$reason) {
showmessage('admin_reason_invalid');
}
}
CODE:
/**
* 发送操作理由报告给帖子作者
* @para array $var
* @para string $item
*/
function sendreasonpm($var, $item) {
global $$var;
${$var}['subject'] = strtr(${$var}['subject'], array_flip(get_html_translation_table(HTML_ENTITIES)));
${$var}['dateline'] = gmdate($GLOBALS['_DCACHE']['settings']['dateformat'].' '.$GLOBALS['_DCACHE']['settings']['timeformat'], ${$var}['dateline'] + ($GLOBALS['timeoffset'] * 3600));
sendpm(${$var}['authorid'], $item.'_subject', $item.'_message');
}
CODE:
/**
* 得到一个下拉列表,这个列表是版主操作理由选择
*
* @return string $select
*/
function modreasonselect() {
global $_DCACHE;
if(!isset($_DCACHE['modreasons']) || !is_array($_DCACHE['modreasons'])) {
@include DISCUZ_ROOT.'./forumdata/cache/cache_topicadmin.php';
}
$select = '';
foreach($_DCACHE['modreasons'] as $reason) {
$select .= $reason ? '<option value="'.dhtmlspecialchars($reason).'">'.$reason.'</option>' : '<option value="">--------</option>';
}
return $select;
}
CODE:
/**
* 登陆检查,看看是不是在十五分钟已经登陆五次了
*
* @return int
*/
function logincheck() {
global $db, $tablepre, $onlineip, $timestamp;
$query = $db->query("SELECT count, lastupdate FROM {$tablepre}failedlogins WHERE ip='$onlineip'");
if($login = $db->fetch_array($query)) {
if($timestamp - $login['lastupdate'] > 900) {
return 3;
} elseif($login['count'] < 5) {
return 2;
} else {
return 0;
}
} else {
return 1;
}
}
CODE:
/**
* 和上面的那个函数(logincheck)是配对的,看是哪种方式登陆的
* @para int $permission
*
*/
function loginfailed($permission) {
global $db, $tablepre, $onlineip, $timestamp;
switch($permission) {
case 1: $db->query("REPLACE INTO {$tablepre}failedlogins (ip, count, lastupdate) VALUES ('$onlineip', '1', '$timestamp')");
break;
case 2: $db->query("UPDATE {$tablepre}failedlogins SET count=count+1, lastupdate='$timestamp' WHERE ip='$onlineip'");
break;
case 3: $db->query("UPDATE {$tablepre}failedlogins SET count='1', lastupdate='$timestamp' WHERE ip='$onlineip'");
$db->query("DELETE FROM {$tablepre}failedlogins WHERE lastupdate<$timestamp-901", 'UNBUFFERED');
break;
}
}
笨才 发布于2007-05-28 12:07:07
Discuz!源代码分析系列--./include/template.func.php(模板)
本帖不仅仅是分析文件,还把Discuz中模板解析这一原理分析了一下。
我记得我刚开始学PHP的时候,对模板解析实在是觉得很奇怪,不知道这个原理怎么实现的,后来看书看多了也明白有一个著名的Smarty在那,曾经也用过 一段,不过感觉不是很好,就开始分析Discuz的模板技术是怎么实现的了,然后我把这个模板解析的代码分离出来了,觉得很好用,用了一段时间, Discuz的模板解析是用正则表达式替换一些模板中的规定的语言标记,然后呢,写到forumdata/templates中,再用include引用 到index, forumdisplay等等中,和smarty的原理基本上相同,只是功能没有smarty那么多,smarty内建了一个cache来着…连个 User Guide都几百页…
呵呵,不过现在基本上两个都没 用过,正则表达式好是好用,不过正则的效率不是很高,以前看PHP技术文档的时候说能不用正则就尽量不要用,那东西烦着,现在做什么项目基本上用的是框 架,MVC的模式,View中的代码一般不用模板解析出来,混杂php代码在里面,也觉得不错,OOP的开发效率比较高,很多地方重用代码是很开心的~!
Discuz的模板解析要分析出来只要用到两个文件:./include/global.func.php和. /include/template.func.php,global只要一个函数就够了,template要全部的文件下面我就分开讲一下,会比较详 细,大家耐心看:
Section One--./include/global.func.php---->template function
CODE:
function template($file, $templateid = 0, $tpldir = '') {
global $tplrefresh;
$tpldir = $tpldir ? $tpldir : TPLDIR;
$templateid = $templateid ? $templateid : TEMPLATEID;
$tplfile = DISCUZ_ROOT.'./'.$tpldir.'/'.$file.'.htm';
$objfile = DISCUZ_ROOT.'./forumdata/templates/'.$templateid.'_'.$file.'.tpl.php';
if(TEMPLATEID != 1 && $templateid != 1 && !file_exists($tplfile)) {
return template($file, 1, './templates/default/');
}
if($tplrefresh == 1 || ($tplrefresh > 1 && substr($GLOBALS['timestamp'], -1) > $tplrefresh)) {
if(@filemtime($tplfile) > @filemtime($objfile)) {
require_once DISCUZ_ROOT.'./include/template.func.php';
parse_template($file, $templateid, $tpldir);
}
}
return $objfile;
}这个函数一共有三个传入参数:
$file 表示模板名
$templateid 表示模板id
$tpldir 表示模板目录
QUOTE:
CODE:
global $tplrefresh;这个是把$tplrefresh作为一个全局变量,tplrefresh表示是不是刷新模板QUOTE:
CODE:
$tpldir = $tpldir ? $tpldir : TPLDIR;QUOTE:
CODE:
$tplfile = DISCUZ_ROOT.'./'.$tpldir.'/'.$file.'.htm';QUOTE:
CODE:
if(TEMPLATEID != 1 && $templateid != 1 && !file_exists($tplfile)) {QUOTE:
CODE:
if($tplrefresh == 1 || ($tplrefresh > 1 && substr($GLOBALS['timestamp'], -1) > $tplrefresh)) {
笨才 发布于2007-05-28 12:08:37
关于template.func.php文件中函数的分析在下面:
CODE:
//防止非法引用
if(!defined('IN_DISCUZ')) {
exit('Access Denied');
}
CODE:
/**
* 这个是关键模板解析函数,通过正则表达式来替换掉模板中的相关语句,使之变成标准的php语句,写入缓存(./forumdata/template),从而include到页面中显示出来
* @para string $file //解析的模板名,只要文件名就可以了,会自动加上htm,如果有缓存的话就变成"模板id_文件名.tpl.php"
* @para int $templateid //模板的id
* @para string $tpldir //模板所在的目录
*
*/
function parse_template($file, $templateid, $tpldir) {
global $language;
$nest = 5;
$tplfile = DISCUZ_ROOT."./$tpldir/$file.htm";
$objfile = DISCUZ_ROOT."./forumdata/templates/{$templateid}_$file.tpl.php";
if(!@$fp = fopen($tplfile, 'r')) {
dexit("Current template file './$tpldir/$file.htm' not found or have no access!");
} elseif(!include_once language('templates', $templateid, $tpldir)) {
dexit("<br>Current template pack do not have a necessary language file 'templates.lang.php' or have syntax error!");
}
$template = fread($fp, filesize($tplfile));
fclose($fp);
$var_regexp = "((///$[a-zA-Z_/x7f-/xff][a-zA-Z0-9_/x7f-/xff]*)(/[[a-zA-Z0-9_/-/./"/'/[/]/$/x7f-/xff]+/])*)";
$const_regexp = "([a-zA-Z_/x7f-/xff][a-zA-Z0-9_/x7f-/xff]*)";
$template = preg_replace("/([/n/r]+)/t+/s", "//1", $template);
$template = preg_replace("//</!/-/-/{(.+?)/}/-/-/>/s", "{//1}", $template);
$template = preg_replace("//{lang/s+(.+?)/}/ies", "languagevar('//1')", $template);
$template = preg_replace("//{faq/s+(.+?)/}/ies", "faqvar('//1')", $template);
$template = str_replace("{LF}", "<?=/"//n/"?>", $template);
$template = preg_replace("//{(///$[a-zA-Z0-9_/[/]/'/"/$/./x7f-/xff]+)/}/s", "<?=//1?>", $template);
$template = preg_replace("/$var_regexp/es", "addquote('<?=//1?>')", $template);
$template = preg_replace("//</?/=/</?/=$var_regexp/?/>/?/>/es", "addquote('<?=//1?>')", $template);
$template = "<? if(!defined('IN_DISCUZ')) exit('Access Denied'); ?>/n$template";
$template = preg_replace("/[/n/r/t]*/{template/s+([a-z0-9_]+)/}[/n/r/t]*/is", "/n<? include template('//1'); ?>/n", $template);
$template = preg_replace("/[/n/r/t]*/{template/s+(.+?)/}[/n/r/t]*/is", "/n<? include template(//1); ?>/n", $template);
$template = preg_replace("/[/n/r/t]*/{eval/s+(.+?)/}[/n/r/t]*/ies", "stripvtags('/n<? //1 ?>/n','')", $template);
$template = preg_replace("/[/n/r/t]*/{echo/s+(.+?)/}[/n/r/t]*/ies", "stripvtags('/n<? echo //1; ?>/n','')", $template);
$template = preg_replace("/[/n/r/t]*/{elseif/s+(.+?)/}[/n/r/t]*/ies", "stripvtags('/n<? } elseif(//1) { ?>/n','')", $template);
$template = preg_replace("/[/n/r/t]*/{else/}[/n/r/t]*/is", "/n<? } else { ?>/n", $template);
for($i = 0; $i < $nest; $i++) {
$template = preg_replace("/[/n/r/t]*/{loop/s+(/S+)/s+(/S+)/}[/n/r]*(.+?)[/n/r]*/{//loop/}[/n/r/t]*/ies", "stripvtags('/n<? if(is_array(//1)) { foreach(//1 as //2) { ?>','/n//3/n<? } } ?>/n')", $template);
$template = preg_replace("/[/n/r/t]*/{loop/s+(/S+)/s+(/S+)/s+(/S+)/}[/n/r/t]*(.+?)[/n/r/t]*/{//loop/}[/n/r/t]*/ies", "stripvtags('/n<? if(is_array(//1)) { foreach(//1 as //2 => //3) { ?>','/n//4/n<? } } ?>/n')", $template);
$template = preg_replace("/[/n/r/t]*/{if/s+(.+?)/}[/n/r]*(.+?)[/n/r]*/{//if/}[/n/r/t]*/ies", "stripvtags('/n<? if(//1) { ?>','/n//2/n<? } ?>/n')", $template);
}
$template = preg_replace("//{$const_regexp/}/s", "<?=//1?>", $template);
$template = preg_replace("/ /?/>[/n/r]*/</? /s", " ", $template);
if(!@$fp = fopen($objfile, 'w')) {
dexit("Directory './forumdata/templates/' not found or have no access!");
}
$template = preg_replace("//"(http)?[/w/.//:]+/?[^/"]+?&[^/"]+?/"/e", "transamp('//0')", $template);
$template = preg_replace("//<script[^/>]*?src=/"(.+?)/".*?/>/s*/<//script/>/ise", "stripscriptamp('//1')", $template);
flock($fp, 2);
fwrite($fp, $template);
fclose($fp);
}
CODE:
/**
* 几个替换,过滤掉一些东西
* @para string $str
*
* @return string
*/
function transamp($str) {
$str = str_replace('&', '&', $str);
$str = str_replace('&', '&', $str);
$str = str_replace('/"', '"', $str);
return $str;
}
CODE:
/**
* 从正则表达式来看是给ubb代码去掉一个/符号的,应该是为安全性着想的
* @para string $val
*
* @return string
*/
function addquote($var) {
return str_replace("///"", "/"", preg_replace("//[([a-zA-Z0-9_/-/./x7f-/xff]+)/]/s", "['//1']", $var));
}
CODE:
/**
* 把一个字符用语言包中的来替换,没有找到的话就用!string来替换
* @para string $val
*
* @return string
*/
function languagevar($var) {
if(isset($GLOBALS['language'][$var])) {
return $GLOBALS['language'][$var];
} else {
return "!$var!";
}
}
CODE:
/**
* FAQ中把id和关建字用一个有效的链接来替换
* @para array $val
*
* @return string
*/
function faqvar($var) {
global $_DCACHE;
include_once DISCUZ_ROOT.'./forumdata/cache/cache_faqs.php';
if(isset($_DCACHE['faqs'][$var])) {
return '<a href="faq.php?action=message&id='.$_DCACHE['faqs'][$var]['id'].'" target="_blank">'.$_DCACHE['faqs'][$var]['keyword'].'</a>';
} else {
return "!$var!";
}
}
CODE:
/**
* 去掉自定义的一些tag
* @para string $expr
* @para string $statement
* @return string
*/
function stripvtags($expr, $statement) {
$expr = str_replace("///"", "/"", preg_replace("//</?/=(///$.+?)/?/>/s", "//1", $expr));
$statement = str_replace("///"", "/"", $statement);
return $expr.$statement;
}
CODE:
/**
* 作用是把&符号的html编码形式换成&,然后换成javascript引用的形式。
* @para string $s
*
* @return string
*/
function stripscriptamp($s) {
$s = str_replace('&', '&', $s);
return "<script src=/"$s/" type=/"text/javascript/"></script>";
}
笨才 发布于2007-05-28 12:13:35
Discuz!5.5源代码分析系列-AJAX工作原理,底层代码分析
Discuz的ajax原理实际上是很简单的,当然,说到ajax肯定是用XMLHttpRequest这个对象了,不过我曾经也看到国外的牛人写过一篇 文章叫做不用XMLHttpRequest对象来实现ajax,而且还解决了跨域的问题,真是大开了眼界~!好了,说正事,Dz的ajax用到的文件不是 很多,列举如下:
QUOTE:
./include/javascript/common.jsQUOTE:
./include/javascript/ajax.jsQUOTE:
./ajax.phpQUOTE:
CODE:
var Ajaxs = new Array();QUOTE:
CODE:
aj.processHandle = function() {CODE:
var profile_seccode_invalid = '{lang register_profile_seccode_invalid}';QUOTE:
CODE:
aj.get = function(targetUrl, resultHandle) {
笨才 发布于2007-05-28 12:23:19
有了这些理论的基础就可以分析一下ajax的具体实现了,下面就以注册过程中的检查用户名在数据库是不是存在并给用户提示这样一个ajax过程进行全程分析。
用到如下的几个文件:
QUOTE:
./register.php
其实register.php这个文件没什么多大的关系,不过register.htm模板是通过它解析过来的,所以就提出来了。
大家都知道在注册过程中是在输完用户名并输入密码的时候才会触发事件检查是不是用户存在,所以很明显,这个是input的onBlur事件。
好了,现在看看./templates/default/register.htm这个文件。
QUOTE:
CODE:
<tr>CODE:
function checkusername() {CODE:
function ajaxresponse(objname, data) {CODE:
function warning(obj, msg) {
接下来当然是要分析这个ajax.php是怎么一回事,它做了哪些使function(s)中能返回我们要的东西。由于只分析检查用户名这一个部分,我这里就只分析action=checkuser这一部分了。
QUOTE:
CODE:
elseif($action == 'checkusername') {CODE:
showmessage('succeed');注意当所有的判断都成功的话就说明合法了,会调用showmessage来显示一个succeed。QUOTE:
最后说一下为什么这里的showmessage不是我们理解的那个跳转了。http://www.discuz.net/viewthread.php?tid=612197,我在这里分析了一下。
转自:http://blog.csdn.net/freefis/article/details/1839545