利用JS获取IE客户端IP及MAC的实现

    在做B/S结构的系统时,我们常常需要获取客户端的一些信息,如IP和MAC,以结合身份验证。在ASP.NET中,要获取服务器端的MAC很容易,但是要获取客户端的MAC的地址确要花费一翻心思,通常的做法是调用Win32API或直接调用nbtstat命令,这样做有很多问题,而另一种方法就是直接用客户端脚本,我们这里用Javascript,这样做的好处是不需要服务器端进行处理,有客户端自行获取,传递到服务器端,且速度和可靠性都比在服务器端获取好。
        具体实现的html和javascript如下:
<HTML><HEAD><TITLE>WMI Scripting HTML</TITLE>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<SCRIPT language=JScript event="OnCompleted(hResult,pErrorObject, pAsyncContext)" for=foo>
 document.forms[0].txtMACAddr.value=unescape(MACAddr);
 document.forms[0].txtIPAddr.value=unescape(IPAddr);
 document.forms[0].txtDNSName.value=unescape(sDNSName);
 //document.formbar.submit();
  </SCRIPT>

<SCRIPT language=JScript event=OnObjectReady(objObject,objAsyncContext) for=foo>
   if(objObject.IPEnabled != null && objObject.IPEnabled != "undefined" && objObject.IPEnabled == true)
   {
    if(objObject.MACAddress != null && objObject.MACAddress != "undefined")
    MACAddr = objObject.MACAddress;
    if(objObject.IPEnabled && objObject.IPAddress(0) != null && objObject.IPAddress(0) != "undefined")
    IPAddr = objObject.IPAddress(0);
    if(objObject.DNSHostName != null && objObject.DNSHostName != "undefined")
    sDNSName = objObject.DNSHostName;
    }
  </SCRIPT>

<META content="MSHTML 6.00.2800.1106" name=GENERATOR></HEAD>
<BODY>
<OBJECT id=locator classid=CLSID:76A64158-CB41-11D1-8B02-00600806D9B6 VIEWASTEXT></OBJECT>
<OBJECT id=foo classid=CLSID:75718C9A-F029-11d1-A1AC-00C04FB6C223></OBJECT>
<SCRIPT language=JScript>
   var service = locator.ConnectServer();
   var MACAddr ;
   var IPAddr ;
   var DomainAddr;
   var sDNSName;
   service.Security_.ImpersonationLevel=3;
   service.InstancesOfAsync(foo, 'Win32_NetworkAdapterConfiguration');
   </SCRIPT>

<FORM id=formfoo name=formbar action=NICPost.asp method=post><INPUT value=00:05:5D:0E:C7:FA name=txtMACAddr> <INPUT value=192.168.0.2 name=txtIPAddr> <INPUT value=typ name=txtDNSName> </FORM></BODY></HTML>
        关键是用到两个ActiveX:
        <OBJECT id=locator classid=CLSID:76A64158-CB41-11D1-8B02-00600806D9B6 VIEWASTEXT></OBJECT>
        <OBJECT id=foo classid=CLSID:75718C9A-F029-11d1-A1AC-00C04FB6C223></OBJECT>
        不过这两个ActiveX都是系统自带,不用去下载或注册。
        接下来的工作就是用脚本和ActiveX交互,脚本可以是js或Vbs我个人喜欢用js。

JS函数实现鼠标指向后带图片的提示效果

  当鼠标移到产品缩略图上时能弹出显示大图,用JS写两个函数即可实现:

  一个函数在鼠标移到图片上调用,显示隐藏层并将图片载入到层中;

  另一个函数在鼠标移出图片上调用,清空层的内容并隐藏层。使用时需将"this.src"改为产品大图地址。

以下是引用片段:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>JS函数实现鼠标指向后带图片的提示效果</title>
<script language="javascript">
function showPic(sUrl){
 var x,y;
 x = event.clientX;
 y = event.clientY;
 document.getElementById("Layer1").style.left = x;
 document.getElementById("Layer1").style.top = y;
 document.getElementById("Layer1").innerHTML = "<img src=\"" + sUrl + "\">";
 document.getElementById("Layer1").style.display = "block";
}
function hiddenPic(){
 document.getElementById("Layer1").innerHTML = "";
 document.getElementById("Layer1").style.display = "none";
}
</script>
</head>
<body>
<div id="Layer1" style="display:none;position:absolute;z-index:1;"></div>
<img src="/images/logo.gif" onmouseout="hiddenPic();" onmousemove="showPic(this.src);" />
<p></p>
<img src="/img/200406301.jpg" onmouseout="hiddenPic();" onmousemove="showPic(this.src);" />
</body>
</html>

 

CSS技巧DIV为空时占据空间的解决办法

如果给div元素设置了宽度时,比如width:100%,此时div在IE中(IE6,IE7)将占据物理空间,而在FF中不占据物理空间(正确理解)。为了表述直观,将样式直接写在元素标签内:

此时在IE中到底是什么在影响着最终的显示,又是如何解析的呢?

可能的影响因素:字体大小(font-size),字体行高(line-height),高度(height),溢出(overflow)

我们对上面的代码逐一添加过滤属性(具体的过程有兴趣的朋友,可以私下里实验一下,“自己动手,丰衣足食”!)

在测试的过程中,你会发现IE6和IE7的解析也不尽相同,比如在给div设置了line-height:0; height:0; 的样式后,IE7中显示正常了,不再占据物理空间了,而IE6却依然我行我素,亦或是悲!

最终的测试结果,最简单的方法是,给div设置高度(height)和溢出(overflow)属性:

SEO 标题的最佳下标法

大家都知道,标题是访客进入一个网页(网志)时,最先看到的部分,所以SEOmoz这次提出了「标题的最佳下标法。

原文:Best Practices for Title Tags

翻译:标题的最佳下标法 by Refly

标题的最佳下标法:

质量保证

由于网页的标题都会出现在搜寻引擎的结果显示页面,所以在每个网页的标题都请用心下!

最好使用您网站的标题,或者是您公司的厂牌名称,这样才可以帮助搜寻者快速辨认出您的网页,以后要再度到访也会比较方便。

根据研究证实,有牌的商品跟白牌商品放在一起时,消费者倾向购买有牌商品而不是白牌商品;这个研究应用到搜寻引擎结果上也是相同的,搜寻者倾向点击他们有印象的网站,而不是他们从未听过的网站。当然您也可以透过把关键词放在标题上来吸引搜寻者的点击的。 Continue reading

显示或隐藏层的js代码

显示或隐藏层的js代码,学用于标签的切换.

<script language=javascript>
/*div 切换函数
 o 点击tag的ID,一定要唯一
 total tag的个数
 cname 点击后应用的css类,点击前是cname1,点击后是cname2
 显示或隐藏的div或span名称格式为:sub1,sub2,sub3......

*/

function doClick(o,total,cname){
  o.className=cname+"2";
  var j;
  var id;
  var e;
  for(var i=1;i<=total;i++){
    id ="tag"+i;
    j = document.getElementById(id);
    e = document.getElementById("sub"+i);
    if(id != o.id){
      j.className=cname+"1";
      e.style.display = "none";
    }else{
   e.style.display = "block";
    }
  }
}
</script>

<div id="tag1" class="Tagbg2" onClick="javascript:doClick(this,2,'Tagbg')">报社动态</div>
<div id="tag2" onClick="javascript:doClick(this,2,'Tagbg')">教育新闻</div>
<hr>
<div id="sub1">
<font color=red>这里是tag1的内容</font>
</div>
<div id="sub2" style="display:none;">
<font color=red>这里是tag2的内容</font>
</div>

以下函数为通用函数:

/*
 *tagname 为点击tag的前缀,如tag1,tag2,tag3
* total         为tag的总个数
* cur           为当前点的tag,如tag3,则这里cur=3
* cssname 为点击前后的样式有.点击前为cssname1,点击后为cssname2
*/

function doClickTag(tagname,total,cur,cssname){
  var j;
  var e;
  for(var i=1;i<=total;i++){
  TName = tagname+i;  //menu
  SubName = tagname+"sub_"+i; //submenu
  
    j = document.getElementById(TName);
    e = document.getElementById(SubName);
   
    if(cur != i){    //未选中
    j.className=cssname+"1";
       e.style.display = "none";
    }else{
    j.className=cssname+"2";    
   e.style.display = "block";
    }
   
  }
}
 
网页调用代码如下:
<div id="gk1" class="Tagbg2" onClick="javascript:doClickTag('gk',2,1,'Tagbg')">模拟试题</div>
<div id="gk2" onClick="javascript:doClickTag('gk',2,2,'Tagbg')">历年真题</div>
<div id="gksub_1">
aaa
</div>
<div id="gksub_2" style="display:none">
bbbb
</div>

Adsense美化 - 提高你的广告点击率

Google Adsense的代码只提供了最基本的格式,外加园角和方角!这些广告格式已经被用在很多站点上,所以访客们已经对此类广告代码有了一定的抵御能力!为了能提高广告的点击率,获得更多的收入,我们可以对广告代码的背景进行美化,让其变得更加醒目!

首先来看一个供Wordpress使用的Adsense美化插件:Adsense Beautifier

通过此插件可以在你Google Adsense广告的侧边或者下边加上漂亮的小图片,从而让你的广告更加吸引别人的注意。大家可以先看看使用后的效果图:

插件的使用请自行到作者的主页查看,不在此文讨论范畴! 

使用插件来美化你的Adsense广告非常方便,但这只限于Wordpress上使用。如果你想在其他类型的站点上来美化你的Adsense广告,就需要手工进行Div+Css来布局!先来看看网上常见的几个美化背景:

要实现这样的效果,需要一些简单的CSS知识。当然你要首先准备好一些背景图片,大小根据你要投放的广告尺寸,适当的加宽加长即可!然后上传到你的网站空间或者网上的免费图片存储空间!

我们以468*60的尺寸为例,制作一个480*70的背景图片:

<div style="float: right; background-image: url(图片网址); height: 70px; width: 480px; padding-top: 10px; padding-left: 10px; background-repeat: no-repeat;" >AdSense广告码放在这裡</div>

代码解释:
float: right: 让广告整体靠右边显示,你也可以用left,或者不要这句,广告显示在默认位置!
background-image: url(图片网址): 这几是你的背景图片,填入图片相对或绝对地址即可!
height: 70px; width: 480px: 背景图片的高和宽,为像素尺寸!
padding-top: 10px: 广告代码相对与背景图片上面的间距
padding-left: 10px: 广告代码相对于背景图片左边的间距(上面两项可以在以后进行细调,让广告显示在背景图片的合适位置)
background-repeat: no-repeat: 背景不需要重复

这样,你的广告就可以有一个漂亮的背景图了!当然,你也可以把上面的属性定义到Css文件里,在添加广告的地方直接<div>调用即可,如:

#adsense_468 {
width: 480px;
height: 70px;
background-image: url(图片地址);
padding-top: 10px;
padding-left: 10px;
background-repeat: no-repeat;
}

然后我们在广告位调用
<div id=adsense_468>广告代码放在这里</div>

这样就可以了,很简单!

如何实现博客中的二级域名

我说自己做过博客,面试官就总问我博客中的二级域名实现的问题。这个看似与我编程无关的问题,总翻出来,烦死了。今天有时间,我要解决一下。

首先查到了与此相关的技术:泛域名。

泛域名是以*号为主机名的域名,如果做了泛域名解析,并且生效了,那域名前面不管写什么,只要后面是你的域名,那都可以访问到你的网站上去. 就像“*.icech.com”。那么泛域名有什么功用呢?这么说吧,你在DNS 中建立一个名为“*.icech.com”的泛域名,那么所有就像www.icech.com、news.icech.com、love.icech.com 等等格式的域名都不用建立就会自动生效,他们都会指向建立此泛域名时指向的IP 地址。如果你申请了一个域名,通过这样的测试,你就会知道你申请的域名是不是泛域名了。

建立泛域名的大致步骤是:

1、进入DNS,选“正向查找区域”,单击右键,新建“区域”,输入icech.com

2、选中“icech.com”,单击右键,新建“域”,输入“*”

3、选中“*”,新建“主机”,主机名保持为空,输入相应的IP 地址就OK了。

利用程序来完成虚拟域名的解析

假设我们希望设置一个news.icech.com 的域名,当我们在浏览器中输入“news.icech.com”的域名时,他会转向它的真实地址htttp://www.weste.net/index.htm。一般流程肯定就是,它会首先找到DNS 服务器,并且进行域名与IP 地址的转换,这里因为我们已经设置了泛域名,news.icech.com 就会直接指向icech.com 指向的IP,这之间我们不能做什么其他的设置来改变这一流程。那么我们所要做的就是在这个IP 地址所对应主机的默认WEB页面上做文章,让不同的子域名进行URL重定向,转到它们所希望的URL 网址上去。

1、设置icech.com所在主机所默认的WEB服务的默认文档为index.asp、index.php 或者index.cgi等动态页面,而不能是静态的index.htm 页面。

2、通过ASP、PHP或者CGI程序来进行URL的重定向功能

(1)index.php

$domain=$SERVER_NAME; //取得用户所访问的域名全称

$domain=eregi_replace('.icech.com', '', $domain); //截取域名全称,获取用户所要访问的三级域名,获取所访问的域名全称,可以直接使用PHP系统变量$SERVER_NAME 或 者$HTTP_HOST,注意引用系统内部变量必须大写。事实上PHP 系统内部已经对用户浏览器发送的访问请求头信息进行了全面的分析,并分割成、保存成相应的系统变量,以方便程序使用。第二个语句使用正则替换,查找“.icech.com”并替换成空字符,这样就获得了三级域名。

通常,一个大型的虚拟域名服务都是将用户子域名和其对应URL放在数据库里,这样, 用户可以随时注册新的三级域名和更改域名对应的URL,那么下面的工作就是从数据库中检索出该三级域名对应的URL(数据库检索程序略)。

...... //根据三级域名检索数据库,并得到变量$url,其中存放了该域名对应的URL 地址Header("Location: $url"); //系统重定向,使用户浏览器转向相应URL获得了对应URL 地址之后,我们可以使用PHP的header函数给用户浏览器发送一个重定向信息,让用户转移到相应的URL地址,这样一个完整的虚拟域名服务过程就结束了。

这里我们需要注意的是header函数之前,不能对浏览器有任何输出,否则会产生错误,另外重定向操作中的URL地址应该表述完整,例如:http://www.weste.net/index.htm广告窗口的弹出:常见的虚拟域名服务通常会有弹出广告窗口,是怎么实现的呢?为了能统一控制,必须在重定向用户浏览器之前弹出这个广告框,那么重定向操作就不能简单地使用header函数了,因为这个函数要求使用前不能对浏览器有任何输出。要实现它,我们必须改变方法:

//根据三级域名检索数据库,并得到变量$url,其中存放了该域名对应的URL 地址

echo '<script language="javascript">window.open("adv.htm");</script>';

//输出一段javascript代码,用以打开一个广告窗口,显示广告页adv.htm

echo '<meta http-equiv="refresh" content="0;URL='.$url.'">';

//使用HTML的meta 语句来实现系统重定向,让用户浏览器转向相应URL。

(2)index.asp

<% name=request.querystring("name") %> ‘这样来获取用户所访问的域名全称
trim(name) ‘用trim 函数来截取域名全称,获取用户所要访问的三级域名与数据库对比,如果与数据库所设置的虚拟域名相同,则直接用response.redirect 转向http://www.weste.net/index.htm页面,否则设定另外转向页面。

还有两种方法可以做到解析无限个二级域名

使用程序进行判断调整
iis服务的主机头留空,新建Default.asp文件,并把新建文件的执行优先级设定为最高(IIS设置属性中的文档,将Default.asp移到最上面)。
Default.asp文件代码:
<%
Dim iURL
iURL = Split(Request.ServerVariables("SERVER_NAME"),".")
If Lcase(iURL(0))="www" Then
'此处为网站首页地址,请自行选择
Response.Redirect("index.asp")
Else
'如二级域名所调转地址,请自行更改此处地址
Response.Write( "<frameset><frame src=""**.asp?"&iURL(0)&".index.html""></frameset>")
End If
%>

使用 ISAPI_Rewrite URL处理引擎
先介绍一下ISAPI_Rewrite :
ISAPI_Rewrite是一个强大的基于正则表达式的URL处理引擎。它非常类似于Apache's mod_Rewrite,但它是专为IIS设计的。

ISAPI_Rewrite有两个版本:ISAPI_Rewrite Full与ISAPI_Rewrite Lite。

ISAPI_Rewrite Lite是免费版本,但不支持反向代理功能。
ISAPI_Rewrite Full只能下载到30天的试用版本。

解析二级域名就可以用ISAPI_Rewrite一个规则来实现。
如:
test.test.com 映射成 www.test.com/test/
规则如下:
RewriteCond Host: (?!/.|www|ww)(.*).test.com
RewriteRule (.*) http/://www.test.com/$1$2 [I,R]

discuz代码之 include/global.func.php 初解

<?php
if(!defined('IN_DISCUZ')) {
    exit('Access Denied');
}
//防止非法引用

//base64加密。$string 要加/解密的string,$operation 方法(解密/加密),$key 用来加密的key
function authcode($string, $operation, $key = '') {

    $key = md5($key ? $key : $GLOBALS['discuz_auth_key']);
    $key_length = strlen($key);

    $string = $operation == 'DECODE' ? base64_decode($string) : substr(md5($string.$key), 0, 8).$string;
    $string_length = strlen($string);

    $rndkey = $box = array();
    $result = '';

    for($i = 0; $i <= 255; $i++) {
        $rndkey[$i] = ord($key[$i % $key_length]);
        $box[$i] = $i;
    }

    for($j = $i = 0; $i < 256; $i++) {
        $j = ($j + $box[$i] + $rndkey[$i]) % 256;
        $tmp = $box[$i];
        $box[$i] = $box[$j];
        $box[$j] = $tmp;
    }

    for($a = $j = $i = 0; $i < $string_length; $i++) {
        $a = ($a + 1) % 256;
        $j = ($j + $box[$a]) % 256;
        $tmp = $box[$a];
        $box[$a] = $box[$j];
        $box[$j] = $tmp;
        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
    }

    if($operation == 'DECODE') {
        if(substr($result, 0, 8) == substr(md5(substr($result, 8).$key), 0, 8)) {
            return substr($result, 8);
        } else {
            return '';
        }
    } else {
        return str_replace('=', '', base64_encode($result));
    }

}

//这个是用来清除所有的cookie的
function clearcookies() {
    global $discuz_uid, $discuz_user, $discuz_pw, $discuz_secques, $adminid, $credits;
    dsetcookie('sid', '', -86400 * 365);
    dsetcookie('auth', '', -86400 * 365);
    dsetcookie('visitedfid', '', -86400 * 365);
    dsetcookie('onlinedetail', '', -86400 * 365, 0);

    $discuz_uid = $adminid = $credits = 0;
    $discuz_user = $discuz_pw = $discuz_secques = '';
}

//用来检查积分的最低要求的
function checklowerlimit($creditsarray, $coef = 1) {
    if(is_array($creditsarray)) {
        global $extcredits, $id;
        foreach($creditsarray as $id => $addcredits) {
            if($addcredits * $coef < 0 && $GLOBALS['extcredits'.$id] - $addcredits < $extcredits[$id]['lowerlimit']) {
                showmessage('credits_policy_lowerlimit');
            }
        }
    }
}

//用来完美分词的,也就是把一段中文字只取前面一段,再加一个…,$string 用来分词的串,$length 保留的长度,$dot 最后加点什么
function cutstr($string, $length, $dot = ' ...') {
    global $charset;

    if(strlen($string) <= $length) {
        return $string;
    }

    $string = str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $string);

    $strcut = '';
    if(strtolower($charset) == 'utf-8') {

        $n = $tn = $noc = 0;
        while($n < strlen($string)) {

            $t = ord($string[$n]);
            if($t == 9 || $t == 10 || (32 <= $t && $t <= 126)) {
                $tn = 1; $n++; $noc++;
            } elseif(194 <= $t && $t <= 223) {
                $tn = 2; $n += 2; $noc += 2;
            } elseif(224 <= $t && $t < 239) {
                $tn = 3; $n += 3; $noc += 2;
            } elseif(240 <= $t && $t <= 247) {
                $tn = 4; $n += 4; $noc += 2;
            } elseif(248 <= $t && $t <= 251) {
                $tn = 5; $n += 5; $noc += 2;
     &n
bsp;      } elseif($t == 252 || $t == 253) {
                $tn = 6; $n += 6; $noc += 2;
            } else {
                $n++;
            }

            if($noc >= $length) {
                break;
            }

        }
        if($noc > $length) {
            $n -= $tn;
        }

        $strcut = substr($string, 0, $n);

    } else {
        for($i = 0; $i < $length - strlen($dot) - 1; $i++) {
            $strcut .= ord($string[$i]) > 127 ? $string[$i].$string[++$i] : $string[$i];
        }
    }

    $strcut = str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $strcut);

    return $strcut.$dot;
}

//用来过滤字串的,$string 要过滤的字串,$force 强制过滤
function daddslashes($string, $force = 0) {
    !defined('MAGIC_QUOTES_GPC') && define('MAGIC_QUOTES_GPC', get_magic_quotes_gpc());
    if(!MAGIC_QUOTES_GPC || $force) {
        if(is_array($string)) {
            foreach($string as $key => $val) {
                $string[$key] = daddslashes($val, $force);
            }
        } else {
            $string = addslashes($string);
        }
    }
    return $string;
}

//检查一个日期是否合法,$ymd 日期字串,$sep 分隔符
function datecheck($ymd, $sep='-') {
    if(!empty($ymd)) {
        list($year, $month, $day) = explode($sep, $ymd);
        return checkdate($month, $day, $year);
    } else {
        return FALSE;
    }
}

//用来计算程序运行时间的,论坛底部的debug info
function debuginfo() {
    if($GLOBALS['debug']) {
        global $db, $discuz_starttime, $debuginfo;
        $mtime = explode(' ', microtime());
        $debuginfo = array('time' => number_format(($mtime[1] + $mtime[0] - $discuz_starttime), 6), 'queries' => $db->querynum);
        return TRUE;
    } else {
        return FALSE;
    }
}

//强制退出
function dexit($message = '') {
    echo $message;
    output();
    exit();
}

//过滤HTML代码
function dhtmlspecialchars($string) {
    if(is_array($string)) {
        foreach($string as $key => $val) {
            $string[$key] = dhtmlspecialchars($val);
        }
    } else {
        $string = preg_replace('/&((#(\d{3,5}|x[a-fA-F0-9]{4})|[a-zA-Z][a-z0-9]{2,5});)/', '&\\1',
        str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $string));
    }
    return $string;
}

//用来设置header的
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();
    }
}

//判断文件是不是上传了
function disuploadedfile($file) {
    return function_exists('is_uploaded_file') && (is_uploaded_file($file) || is_uploaded_file(str_replace('\\\\', '\\', $file)));
}

//用来得到上一个页面的地址,也就是来路.$default 这个参数是直接设置一个refer,不用判断得到
function dreferer($default = '') {
    global $referer, $indexname;

    $default = empty($default) ? $indexname : '';
    if(empty($referer) && isset($GLOBALS['_SERVER']['HTTP_REFERER'])) {
        $referer = preg_replace("/([\?&])((sid\=[a-z0-9]{6})(&|$))/i", '\\1', $GLOBALS['_SERVER']['HTTP_REFERER']);
        $referer = substr($referer, -1) == '?' ? substr($referer, 0, -1) : $referer;
    } else {
        $referer = dhtmlspecialchars($referer);
    }

    if(!preg_mat
ch("/(\.php|[a-z]+(\-\d+)+\.html)/", $referer) || strpos($referer, 'logging.php')) {
        $referer = $default;
    }
    return $referer;
}

/**
* 设置cookie用的
* @para string $var cookie名
* @para string $value cookie值
* @para int $life 生存时间
* @para int $prefix cookie前缀

*/
function dsetcookie($var, $value, $life = 0, $prefix = 1) {
    global $cookiepre, $cookiedomain, $cookiepath, $timestamp, $_SERVER;
    setcookie(($prefix ? $cookiepre : '').$var, $value,
        $life ? $timestamp + $life : 0, $cookiepath,
        $cookiedomain, $_SERVER['SERVER_PORT'] == 443 ? 1 : 0);
}

// 删除论坛的附件用的,$filename 附件名,$havethumb 是否有缩略图,$remote 是否为远程附件
function dunlink($filename, $havethumb = 0, $remote = 0) {
    global $authkey, $ftp, $attachdir;
    if($remote) {
        require_once DISCUZ_ROOT.'./include/ftp.func.php';
        if(!$ftp['connid']) {
            if(!($ftp['connid'] = dftp_connect($ftp['host'], $ftp['username'], authcode($ftp['password'], 'DECODE', md5($authkey)), $ftp['attachdir'], $ftp['port'], $ftp['ssl']))) {
                return;
            }
        }
        dftp_delete($ftp['connid'], $filename);
        $havethumb && dftp_delete($ftp['connid'], $filename.'.thumb.jpg');
    } else {
        @unlink($attachdir.'/'.$filename);
        $havethumb && @unlink($attachdir.'/'.$filename.'.thumb.jpg');
    }
}

//生成email连接用的,比如把nicollelord@yahoo.com换成:<a href="mailto:nicollelord@yahoo.com">nicollelord@yahoo.com</a>这样的形式
function emailconv($email, $tolink = 1) {
    $email = str_replace(array('@', '.'), array('@', '.'), $email);
    return $tolink ? '<a href="mailto: '.$email.'">'.$email.'</a>': $email;
}

// 记录错误日志用的, $type 错误类型,$message 错误内容,$halt 发生错误后是不是就马上停止论坛的运行
function errorlog($type, $message, $halt = 1) {
    global $timestamp, $discuz_userss, $onlineip, $_SERVER;
    $user = empty($discuz_userss) ? '' : $discuz_userss.'<br>';
    $user .= $onlineip.'|'.$_SERVER['REMOTE_ADDR'];
    writelog('errorlog', dhtmlspecialchars("$timestamp\t$type\t$user\t".str_replace(array("\r", "\n"), array(' ', ' '), trim($message))));
    if($halt) {
        dexit();
    }
}

//判断访问者是不是robot
function getrobot() {
    if(!defined('IS_ROBOT')) {
        $kw_spiders = 'Bot|Crawl|Spider|slurp|sohu-search|lycos|robozilla';
        $kw_browsers = 'MSIE|Netscape|Opera|Konqueror|Mozilla';
        if(preg_match("/($kw_browsers)/", $_SERVER['HTTP_USER_AGENT'])) {
            define('IS_ROBOT', FALSE);
        } elseif(preg_match("/($kw_spiders)/", $_SERVER['HTTP_USER_AGENT'])) {
            define('IS_ROBOT', TRUE);
        } else {
            define('IS_ROBOT', FALSE);
        }
    }
    return IS_ROBOT;
}

//得到一个文件的扩展名
function fileext($filename) {
    return trim(substr(strrchr($filename, '.'), 1, 10));
}

//用当前时间,会员名,uid,密码,authkey生成一个form hash
function formhash() {
    global $discuz_user, $discuz_uid, $discuz_pw, $timestamp, $discuz_auth_key;
    return substr(md5(substr($timestamp, 0, -7).$discuz_user.$discuz_uid.$discuz_pw.$discuz_auth_key), 8, 8);
}

//生成论坛访问权限的字串,以|隔开,$permstr 访问权限字串
function forumperm($permstr) {
    global $groupid, $extgroupids;

    $groupidarray = array($groupid);
    foreach(explode("\t", $extgroupids) as $extgroupid) {
        if($extgroupid = intval(trim($extgroupid))) {
            $groupidarray[] = $extgroupid;
        }
    }
    return preg_match("/(^|\t)(".implode('|', $groupidarray).")(\t|$)/", $permstr);
}

/**
* 得到用户组,同步groupid和member['groupid'],当会员积分和当前积分不一致更新members表。
* @para int $uid 会员的uid
* @para array $group 会员所属的用户组
* @para array $member
*
* @return string
*/
function getgroupid($uid, $group, &$member) {
    global $creditsformula, $db, $tablepre;

    if(!empty($creditsformula)) {
        $updatearray = array();
        eval("\$credits = round($creditsformula);");

        if($credits != $member['credits']) {
            $updatearray[] =&n
bsp;"credits='$credits'";
        }
        if($group['type'] == 'member' && !($member['credits'] >= $group['creditshigher'] && $member['credits'] < $group['creditslower'])) {
            $query = $db->query("Select groupid FROM {$tablepre}usergroups Where type='member' AND $member[credits]>=creditshigher AND $member[credits]<creditslower LIMIT 1");
            if($db->num_rows($query)) {
                $member['groupid'] = $db->result($query, 0);
                $updatearray[] = "groupid='$member[groupid]'";
            }
        }

        if($updatearray) {
            $db->query("Update {$tablepre}members SET ".implode(', ', $updatearray)." Where uid='$uid'");
        }
    }

    return $member['groupid'];
}

/**
* 这个的作用主要是把序列化后存在于数据库中的会员组到期信息取出来
* @para string $terms
* @para int $expiry
*/
function groupexpiry($terms) {
    $terms = is_array($terms) ? $terms : unserialize($terms);
    $groupexpiry = isset($terms['main']['time']) ? intval($terms['main']['time']) : 0;
    if(is_array($terms['ext'])) {
        foreach($terms['ext'] as $expiry) {
            if((!$groupexpiry && $expiry) || $expiry < $groupexpiry) {
                $groupexpiry = $expiry;
            }
        }
    }
    return $groupexpiry;
}

/**
* 看看一个ip是不是在允许访问的范围内
* @para string $ip
* @para array $accesslist
*
* @return boolean
*/
function ipaccess($ip, $accesslist) {
    return preg_match("/^(".str_replace(array("\r\n", ' '), array('|', ''), preg_quote($accesslist, '/')).")/", $ip);
}

/**
* 判断ip是不是被ban了
* @para string $onlineip

* @return boolean
*/
function ipbanned($onlineip) {
    global $ipaccess, $timestamp, $cachelost;

    if($ipaccess && !ipaccess($onlineip, $ipaccess)) {
        return TRUE;
    }

    $cachelost .= (@include DISCUZ_ROOT.'./forumdata/cache/cache_ipbanned.php') ? '' : ' ipbanned';
    if(empty($_DCACHE['ipbanned'])) {
        return FALSE;
    } else {
        if($_DCACHE['ipbanned']['expiration'] < $timestamp) {
            @unlink(DISCUZ_ROOT.'./forumdata/cache/cache_ipbanned.php');
        }
        return preg_match("/^(".$_DCACHE['ipbanned']['regexp'].")$/", $onlineip);
    }
}

/**
* 检查一个email的合法性
* @para string $email
*/
function isemail($email) {
    return strlen($email) > 6 && preg_match("/^[\w\-\.]+@[\w\-\.]+(\.\w+)+$/", $email);
}

/**
* Discuz语言解析用到的东西,即按照需要装入语言包这个数组
* @para string $file 语言文件(如:templates, email, actions等)
* @para int $templateid 用的是哪套模板中的,若没有的话用TEMPLATEID这个常数取代
* @para string $tpldir 模板所在的目录
*
* @return array or false
*/
function language($file, $templateid = 0, $tpldir = '') {
    $tpldir = $tpldir ? $tpldir : TPLDIR;
    $templateid = $templateid ? $templateid : TEMPLATEID;

    $languagepack = DISCUZ_ROOT.'./'.$tpldir.'/'.$file.'.lang.php';
    if(file_exists($languagepack)) {
        return $languagepack;
    } elseif($templateid != 1 && $tpldir != './templates/default') {
        return language($file, 1, './templates/default');
    } else {
        return FALSE;
    }
}

/**
* 超经典的分页函数来了
* @para int $num 记录总数
* @para int $perpage 每页的记录数
* @para int $curpage 当前页
* @para string $mpurl 这个是用来保留query string中的参数的,打个比方:forumdisplay.php?fid=2,这个就是mpurl了,处理后会变成forumdisplay.php?fid=2&page=xx
* @para int $maxpages 最大的页数
* @para int $page 总页数
* @para int $simple 好像simple如果比一大的话就只有第一页,上一页,下一页,最后页
* @para string $onclick 点击触发的事件,AJAX用的
*/
function multi($num, $perpage, $curpage, $mpurl, $maxpages = 0, $page = 10, $simple = 0, $onclick = '') {
    $multipage = '';
    $mpurl .= strpos($mpurl, '?') ? '&' : '?';
    $onclick = $onclick ? ' onclick="'.$onclick.'(event)"' : '';
    if($num > $perpage) {
        $offset = 2;

        $realpages =&nb
sp;@ceil($num / $perpage);
        $pages = $maxpages && $maxpages < $realpages ? $maxpages : $realpages;

        if($page > $pages) {
            $from = 1;
            $to = $pages;
        } else {
            $from = $curpage - $offset;
            $to = $from + $page - 1;
            if($from < 1) {
                $to = $curpage + 1 - $from;
                $from = 1;
                if($to - $from < $page) {
                    $to = $page;
                }
            } elseif($to > $pages) {
                $from = $pages - $page + 1;
                $to = $pages;
            }
        }

        $multipage = ($curpage - $offset > 1 && $pages > $page ? '<a href="'.$mpurl.'page=1" class="p_redirect"'.$onclick.'>|‹</a>' : '').
            ($curpage > 1 && !$simple ? '<a href="'.$mpurl.'page='.($curpage - 1).'" class="p_redirect">‹‹</a>' : '');
        for($i = $from; $i <= $to; $i++) {
            $multipage .= $i == $curpage ? '<a class="p_curpage">'.$i.'</a>' :
                '<a href="'.$mpurl.'page='.$i.'" class="p_num"'.$onclick.'>'.$i.'</a>';
        }

        $multipage .= ($curpage < $pages && !$simple ? '<a href="'.$mpurl.'page='.($curpage + 1).'" class="p_redirect"'.$onclick.'>››</a>' : '').
            ($to < $pages ? '<a href="'.$mpurl.'page='.$pages.'" class="p_redirect"'.$onclick.'>›|</a>' : '').
            ($curpage == $maxpages ? '<a class="p_redirect" href="misc.php?action=maxpages&pages='.$maxpages.'">›?</a>' : '').
            (!$simple && $pages > $page ? '<a class="p_pages" style="padding: 0px"><input class="p_input" type="text" name="custompage" onKeyDown="if(event.keyCode==13) {window.location=\''.$mpurl.'page=\'+this.value; return false;}"></a>' : '');

        $multipage = $multipage ? '<div class="p_bar">'.(!$simple ? '<a class="p_total"> '.$num.' </a><a class="p_pages"> '.$curpage.'/'.$realpages.' </a>' : '').$multipage.'</div>' : '';
    }
    return $multipage;
}

/*
* 输出用的,这个时候可以做一点事情,比如说:把sid用正则写到form里面,rewrite规则启用后把论坛里面的forumdisplay.php?fid=1&page=2用正则换成forum-1-2.html。
* 并把ftp连接关掉,写入cache
*/
function output() {
    global $sid, $transsidstatus, $rewritestatus, $ftp;

    if(($transsidstatus = empty($GLOBALS['_DCOOKIE']['sid']) && $transsidstatus) || in_array($rewritestatus, array(2, 3))) {
        if($transsidstatus) {
            $searcharray = array
                (
                "/\<a(\s*[^\>]+\s*)href\=([\"|\']?)([^\"\'\s]+)/ies",
                "/(\<form.+?\>)/is"
                );
            $replacearray = array
                (
                "transsid('\\3','<a\\1href=\\2')",
                "\\1\n<input type=\"hidden\" name=\"sid\" value=\"$sid\">"
                );
        } else {
            $searcharray = array
                (
                //"/\<a href\=\"index\.php\"\>/",
                "/\<a href\=\"forumdisplay\.php\?fid\=(\d+)(&page\=(\d+))?\"([^\>]*)\>/e",
                "/\<a href\=\"viewthread\.php\?tid\=(\d+)(&extra\=page\%3D(\d+))?(&page\=(\d+))?\"([^\>]*)\>/e",
&nbs
p;               "/\<a href\=\"viewpro\.php\?(uid\=(\d+)|username\=([^&]+?))\"([^\>]*)\>/e",
                "/\<a href\=\"space\.php\?(uid\=(\d+)|username\=([^&]+?))\"([^\>]*)\>/e"
                );
            $replacearray = array
                (
                //"<a href=\"index.html\">",
                "rewrite_forum('\\1', '\\3', '\\4')",
                "rewrite_thread('\\1', '\\5', '\\3', '\\6')",
                "rewrite_profile('\\2', '\\3', '\\4')",
                "rewrite_space('\\2', '\\3', '\\4')"
                );
        }

        $content = preg_replace($searcharray, $replacearray, ob_get_contents());
        ob_end_clean();
        $GLOBALS['gzipcompress'] ? ob_start('ob_gzhandler') : ob_start();

        echo $content;
    }
    if($ftp['connid']) {
        @ftp_close($ftp['connid']);
    }
    $ftp = array();

    if(defined('CACHE_FILE') && CACHE_FILE && !defined('CACHE_FORBIDDEN')) {
        global $cachethreaddir;
        if(diskfreespace(DISCUZ_ROOT.'./'.$cachethreaddir) > 1000000) {
            $fp = fopen(CACHE_FILE, 'w');
            if($fp) {
                flock($fp, LOCK_EX);
                fwrite($fp, empty($content) ? ob_get_contents() : $content);
            }
            @fclose($fp);
        }
    }
}

/*
*这一段都是rewrite规则,和上一个函数相映成趣
* @para int $tid 帖子的id
* @para int $page 页数
* @para int $prevpage 上一页
* @para string $extra 附加的东东
* @return string 返回一个链接,如: <a href = "thread-1-1.html">
*/

function rewrite_thread($tid, $page = 0, $prevpage = 0, $extra = '') {
    return '<a href="thread-'.$tid.'-'.($page ? $page : 1).'-'.($prevpage ? $prevpage : 1).'.html"'.stripslashes($extra).'>';
}

function rewrite_forum($fid, $page = 0, $extra = '') {
    return '<a href="forum-'.$fid.'-'.($page ? $page : 1).'.html"'.stripslashes($extra).'>';
}

function rewrite_profile($uid, $username, $extra = '') {
    return '<a href="profile-'.($uid ? 'uid-'.$uid : 'username-'.$username).'.html"'.stripslashes($extra).'>';
}

function rewrite_space($uid, $username, $extra = '') {
    return '<a href="space-'.($uid ? 'uid-'.$uid : 'username-'.$username).'.html"'.stripslashes($extra).'>';
}

// 访问时段检查,$periods 允许访问的时段,$showmessage 如果不允许访问的时段会员访问了的话出现的自定义提示
function periodscheck($periods, $showmessage = 1) {
    global $timestamp, $disableperiodctrl, $_DCACHE, $banperiods;

    if(!$disableperiodctrl && $_DCACHE['settings'][$periods]) {
        $now = gmdate('G.i', $timestamp + $_DCACHE['settings']['timeoffset'] * 3600);
        foreach(explode("\r\n", str_replace(':', '.', $_DCACHE['settings'][$periods])) as $period) {
            list($periodbegin, $periodend) = explode('-', $period);
            if(($periodbegin > $periodend && ($now >= $periodbegin || $now < $periodend)) || ($oeriodbegin < $periodend && $now >= $periodbegin && $now < $periodend)) {
                $banperiods = str_replace("\r\n", ', ', $_DCACHE['settings'][$periods]);
                if($showmessage) {
                    showmessage('period_nopermission', NULL, 'NOPERM');
                } else {
                    return TRUE;
                }
            }
        }
    }
    return FALSE;
}

//加密安全提问的,MD5加密
function quescrypt($questionid, $answer) {
    return $questionid > 0 && $answer != '' ? substr(md5($answer.md5($questionid)), 16, 8) : '';
}

//生成随机数,$length 要生成的长度, $numeric 传入一个非零的数表示要生成的全是数字
function 
random($length, $numeric = 0) {
    PHP_VERSION < '4.2.0' && mt_srand((double)microtime() * 1000000);
    if($numeric) {
        $hash = sprintf('%0'.$length.'d', mt_rand(0, pow(10, $length) - 1));
    } else {
        $hash = '';
        $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
        $max = strlen($chars) - 1;
        for($i = 0; $i < $length; $i++) {
            $hash .= $chars[mt_rand(0, $max)];
        }
    }
    return $hash;
}

//删除目录和文件用的,$dirname 要删除的目录名,$keepdir 是否在删除文件后保留目录,也就是只清空目录
function removedir($dirname, $keepdir = FALSE) {

    $dirname = wipespecial($dirname);

    if(!is_dir($dirname)) {
        return FALSE;
    }
    $handle = opendir($dirname);
    while(($file = readdir($handle)) !== FALSE) {
        if($file != '.' && $file != '..') {
            $dir = $dirname . DIRECTORY_SEPARATOR . $file;
            is_dir($dir) ? removedir($dir) : unlink($dir);
        }
    }
    closedir($handle);
    return !$keepdir ? (@rmdir($dirname) ? TRUE : FALSE) : TRUE;
}

//发信件用的
function sendmail($email_to, $email_subject, $email_message, $email_from = '') {
    extract($GLOBALS, EXTR_SKIP);
    require DISCUZ_ROOT.'./include/sendmail.inc.php';
}

//发送PM的函数
function sendpm($toid, $subject, $message, $fromid = '', $from = '') {
    extract($GLOBALS, EXTR_SKIP);
    include language('pms');

    if(isset($language[$subject])) {
        eval("\$subject = addslashes(\"".$language[$subject]."\");");
    }
    if(isset($language[$message])) {
        eval("\$message = addslashes(\"".$language[$message]."\");");
    }

    if(!$fromid && !$from) {
        $fromid = $discuz_uid;
        $from = $discuz_user;
    }

    $pmids = array();
    foreach(explode(',', $toid) as $uid) {
        if(is_numeric($uid)) {
            $query = $db->query("Insert INTO {$tablepre}pms (msgfrom, msgfromid, msgtoid, folder, new, subject, dateline, message)
                VALUES ('$from', '$fromid', '$uid', 'inbox', '1', '$subject', '$timestamp', '$message')");
            if($query) {
                $pmids[] = $uid;
            }
        }
    }

    if($toid = implodeids($pmids)) {
        $db->query("Update {$tablepre}members SET newpm='1' Where uid IN ($toid)");
    }
}

/**
* 大家熟悉的showmesage终于出现~!包含了ajax效果了
* @para string $message 显示在跳转页面的信息,比如:您已成功登陆……
* @para string $url_forword 下一个url,过三秒会自动跳转过去
* @para string $extra 这个用来控制一些特殊的显示,比如:HALTED, NOPERM,这样可以控制一些特殊场合
*/

function showmessage($message, $url_forward = '', $extra = '') {
    extract($GLOBALS, EXTR_SKIP);
    global $extrahead, $discuz_action, $debuginfo, $seccode, $fid, $tid, $supe_fromsupesite, $supe_jumpurl, $supe, $charset, $show_message, $_DCACHE;
    define('CACHE_FORBIDDEN', TRUE);
    $supe_messagetpl = $supe_error = '';
    $show_message = $message;
    $msgforward = unserialize($_DCACHE['settings']['msgforward']);
    $msgforward['refreshtime'] = intval($msgforward['refreshtime']);
    $url_forward = empty($url_forward) ? '' : (empty($_DCOOKIE['sid']) && $transsidstatus ? transsid($url_forward) : $url_forward);

    if($supe_fromsupesite && $supe['status']) {
        $supe_messagetpl = 'supesite_';
        $extra = '';
        $supe_error = $url_forward ? false : true;
        $url_forward = !empty($supe_jumpurl) && !$supe_error ? urldecode($supe_jumpurl) :  $url_forward;
    } elseif($url_forward && empty($_GET['inajax']) && $msgforward['quick'] && $msgforward['messages'] && @in_array($message, $msgforward['messages'])) {
        updatesession();
        dheader("location: ".str_replace('&', '&', $url_forward));
    }

    if(in_array($extra, array('HALTED', 'NOPERM'))) {
        $fid = $tid =&nbs
p;0;
        $discuz_action = 254;
    } else {
        $discuz_action = 255;
    }

    include language('messages');

    if(isset($language[$message])) {
        $supe_pre = $supe_fromsupesite ? 'supe_' : '';
        eval("\$show_message = \"".($language[$supe_pre.$message] ? $language[$supe_pre.$message] : $language[$message])."\";");
        unset($supe_pre);
    }

    ajaxtemplate('showmessage_ajax');

    $extrahead .= $url_forward ? '<meta http-equiv="refresh" content="'.$msgforward['refreshtime'].' url='.$url_forward.'">' : '';

    if($advlist = $advlist['redirect']) {
        foreach($advlist AS $type => $redirectadvs) {
            $advlist[$type] = $redirectadvs[array_rand($redirectadvs)];
        }
    }

    if($extra == 'NOPERM' && !$passport_status) {
        //get secure code checking status (pos. -2)
        if($seccodecheck = substr(sprintf('%05b', $seccodestatus), -2, 1)) {
            $seccode = random(6, 1) + $seccode{0} * 1000000;
        }
        include template('nopermission');
    } else {
        include template($supe_messagetpl.'showmessage');
    }
    dexit();
}

//用来计算显示的星星月亮太阳,$num 等级数
function showstars($num) {
    global $starthreshold;

    $alt = 'alt="Rank: '.$num.'"';
    if(empty($starthreshold)) {
        for($i = 0; $i < $num; $i++) {
            echo '<img src="'.IMGDIR.'/star_level1.gif" '.$alt.' />';
        }
    } else {
        for($i = 3; $i > 0; $i--) {
            $numlevel = intval($num / pow($starthreshold, ($i - 1)));
            $num = ($num % pow($starthreshold, ($i - 1)));
            for($j = 0; $j < $numlevel; $j++) {
                echo '<img src="'.IMGDIR.'/star_level'.$i.'.gif" '.$alt.' />';
            }
        }
    }
}

//得到站点
function site() {
    return $_SERVER['HTTP_HOST'];
}

//这个看成函数重载也无妨,功能就是查找$haystack是不是在$needle中存在
function strexists($haystack, $needle) {
    return !(strpos($haystack, $needle) === FALSE);
}

//验证码转换
function seccodeconvert(&$seccode) {
    $seccode = substr($seccode, -6);
    $s = sprintf('%04s', base_convert($seccode, 10, 24));
    $seccode = '';
    $seccodeunits = 'BCEFGHJKMPQRTVWXY2346789';
    for($i = 0; $i < 4; $i++) {
        $unit = ord($s{$i});
        $seccode .= ($unit >= 0x30 && $unit <= 0x39) ? $seccodeunits[$unit - 0x30] : $seccodeunits[$unit - 0x57];
    }
}

//提交后的检查,主要是检查验证码,安全提问和来路是不是正常。
function submitcheck($var, $allowget = 0, $seccodecheck = 0, $secqaacheck = 0) {
    if(empty($GLOBALS[$var])) {
        return FALSE;
    } else {
        global $_SERVER, $seccode, $seccodeverify, $secanswer, $_DCACHE;
        if($allowget || ($_SERVER['REQUEST_METHOD'] == 'POST' && $GLOBALS['formhash'] == formhash() && (empty($_SERVER['HTTP_REFERER']) ||
            preg_replace("/https?:\/\/([^\:\/]+).*/i", "\\1", $_SERVER['HTTP_REFERER']) == preg_replace("/([^\:]+).*/", "\\1", $_SERVER['HTTP_HOST'])))) {
                if($seccodecheck) {
                    $tmp = $seccode{0};
                    seccodeconvert($seccode);
                    if(strtoupper($seccodeverify) != $seccode) {
                        showmessage('submit_seccode_invalid');
                    }
                $seccode = random(6, 1) + $tmp * 1000000;
                }
            if($secqaacheck) {
                    require_once DISCUZ_ROOT.'./forumdata/cache/cache_secqaa.php';
  
;                  if(md5($secanswer) != $_DCACHE['secqaa'][substr($seccode, 0, 1)]['answer']) {
                            showmessage('submit_secqaa_invalid');
                    }
                $seccode = random(1, 1) * 1000000 + substr($seccode, -6);
                }
            return TRUE;
        } else {
            showmessage('submit_invalid');
        }
    }
}

//另一个提交检查,检查super site的提交的
function supe_submitcheck($allowget = 0, $timespan = 300) {
    global $supe_seccode, $timestamp, $_DCOOKIE, $supe, $supe_fromsupesite;
    $supe_hash = isset($_GET['supe_hash']) || isset($_POST['supe_hash']) ?
        (isset($_GET['supe_hash']) ? $_GET['supe_hash'] : $_POST['supe_hash']) :
        (isset($_DCOOKIE['supe_hash']) ? $_DCOOKIE['supe_hash'] : '');
    if($supe_fromsupesite && $supe['status'] && ($allowget || $_SERVER['REQUEST_METHOD'] == 'POST') && $supe_hash && !empty($supe_seccode)) {
        list($check_timestamp, $check_seccode) = explode("\t", authcode($supe_hash, 'DECODE'));
        if($timestamp - $check_timestamp <= $timespan && $check_seccode == $supe_seccode) {
            return TRUE;
        }
        showmessage('submit_invalid');
    }
    return FALSE;
}

/**
* 另外一个重大函数来了,那就是模板解析,绝对Discuz核心
* @para string $file 模板文件(如:discuz, forumdata, viewthread等)
* @para int $templateid 用的是哪套模板中的,若没有的话用TEMPLATEID这个常数取代
* @para string $tpldir 模板所在的目录

* @return string 解析好的模板文件,通过include template('xxx')这样引用到文件,framework的MVC也是这样一个模式的
*/
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;
}

//得到url中的sid
function transsid($url, $tag = '', $wml = 0) {
    global $sid;
    $tag = stripslashes($tag);
    if(!$tag || (!preg_match("/^(http:\/\/|mailto:|#|javascript)/i", $url) && !strpos($url, 'sid='))) {
        if($pos = strpos($url, '#')) {
            $urlret = substr($url, $pos);
            $url = substr($url, 0, $pos);
        } else {
            $urlret = '';
        }
        $url .= (strpos($url, '?') ? ($wml ? '&' : '&') : '?').'sid='.$sid.$urlret;
    }
    return $tag.$url;
}

//生成主题分类下拉列表
function typeselect($curtypeid = 0) {
    if($threadtypes = $GLOBALS['forum']['threadtypes']) {
        $html = '<select name="typeid"><option value="0"> </option>';
        foreach($threadtypes['types'] as $typeid => $name) {
            $html .= '<option value="'.$typeid.'" '.($curtypeid == $typeid ? 'selected' : '').'>'.strip_tags($name).'</option>';
        }
        $html .= '</select>';
        return $html;
    } else {
        return '';
    }
}

//更新积分用到的函数,$uids 要更新的uid,$creditsarray 要更新的积分,$coef 单位,$extrasql 附加的sql语句
function updatecredits($uids, $creditsarray, $coef = 1, $extrasql = '') {
    if($uids && ((!empty($creditsarray) && is_array($creditsarray)) || $extrasql)) {
        global $db, $tablepre;
        $credi
tsadd = $comma = '';
        foreach($creditsarray as $id => $addcredits) {
            $creditsadd .= $comma.'extcredits'.$id.'=extcredits'.$id.'+('.intval($addcredits).')*('.$coef.')';
            $comma = ', ';
        }

        if($creditsadd || $extrasql) {
            $db->query("Update {$tablepre}members SET $creditsadd ".($creditsadd && $extrasql ? ', ' : '')." $extrasql Where uid IN ('$uids')", 'UNBUFFERED');
        }
    }
}

//把session更新一下,更新了如下的表:onlinetime, members, sessions
function updatesession() {
    if(!empty($GLOBALS['sessionupdated'])) {
        return TRUE;
    }

    global $db, $tablepre, $sessionexists, $sessionupdated, $sid, $onlineip, $discuz_uid, $discuz_user, $timestamp, $lastactivity, $seccode,
        $pvfrequence, $spageviews, $lastolupdate, $oltimespan, $onlinehold, $groupid, $styleid, $invisible, $discuz_action, $fid, $tid, $bloguid;

    $fid = intval($fid);
    $tid = intval($tid);

    if($oltimespan && $discuz_uid && $lastactivity && $timestamp - ($lastolupdate ? $lastolupdate : $lastactivity) > $oltimespan * 60) {
        $lastolupdate = $timestamp;
        $db->query("Update {$tablepre}onlinetime SET total=total+'$oltimespan', thismonth=thismonth+'$oltimespan', lastupdate='$timestamp' Where uid='$discuz_uid' AND lastupdate<='".($timestamp - $oltimespan * 60)."'");
        if(!$db->affected_rows()) {
            $db->query("Insert INTO {$tablepre}onlinetime (uid, thismonth, total, lastupdate)
                VALUES ('$discuz_uid', '$oltimespan', '$oltimespan', '$timestamp')", 'SILENT');
        }
    } else {
        $lastolupdate = intval($lastolupdate);
    }

    if($sessionexists == 1) {
        if($pvfrequence && $discuz_uid) {
            if($spageviews >= $pvfrequence) {
                $pageviewsadd = ', pageviews=\'0\'';
                $db->query("Update {$tablepre}members SET pageviews=pageviews+'$spageviews' Where uid='$discuz_uid'", 'UNBUFFERED');
            } else {
                $pageviewsadd = ', pageviews=pageviews+1';
            }
        } else {
            $pageviewsadd = '';
        }
        $db->query("Update {$tablepre}sessions SET uid='$discuz_uid', username='$discuz_user', groupid='$groupid', styleid='$styleid', invisible='$invisible', action='$discuz_action', lastactivity='$timestamp', lastolupdate='$lastolupdate', seccode='$seccode', fid='$fid', tid='$tid', bloguid='$bloguid' $pageviewsadd Where sid='$sid'");
    } else {
        $ips = explode('.', $onlineip);

        $db->query("Delete FROM {$tablepre}sessions Where sid='$sid' or lastactivity<($timestamp-$onlinehold) or ('$discuz_uid'<>'0' AND uid='$discuz_uid') or (uid='0' AND ip1='$ips[0]' AND ip2='$ips[1]' AND ip3='$ips[2]' AND ip4='$ips[3]' AND lastactivity>$timestamp-60)");
        $db->query("Insert INTO {$tablepre}sessions (sid, ip1, ip2, ip3, ip4, uid, username, groupid, styleid, invisible, action, lastactivity, lastolupdate, seccode, fid, tid, bloguid)
            VALUES ('$sid', '$ips[0]', '$ips[1]', '$ips[2]', '$ips[3]', '$discuz_uid', '$discuz_user', '$groupid', '$styleid', '$invisible', '$discuz_action', '$timestamp', '$lastolupdate', '$seccode', '$fid', '$tid', '$bloguid')", 'SILENT');
        if($discuz_uid && $timestamp - $lastactivity > 21600) {
            if($oltimespan && $timestamp - $lastactivity > 86400) {
                $query = $db->query("Select total FROM {$tablepre}onlinetime Where uid='$discuz_uid'");
                $oltimeadd = ', oltime='.round(intval($db->result($query, 0)) / 60);
            } else {
                $oltimeadd = '';
            }
            $db->query("Update {$tablepre}members SET lastip='$onlineip', lastvisit=lastactivity, lastactivity='$timestamp' $oltimeadd Where uid='$discuz_uid'", 'UNBUFFERED');
        }
    }

    $sessionupdated = 1;
}

//更新版主工作统计的,$modaction 进行的何种操作(高亮,关闭,提升…),$posts 一次进行了的个数
function updatemodworks($modaction, $posts = 1) {
    global $modworkstatus, $db, $tablepre, $discuz_uid, $timestamp, $_DCACHE;
    $today = gmdate('Y-m-d', $timestamp + $_DCACHE['settings']['timeoffset'] * 3600);
    if($modworkstatus && $modaction && $posts) {
        $db->query("Update {$tablepre}modworks SET count=count+1, posts=posts+'$posts' Where uid='$discuz_uid' AND modaction='$modaction' AND dateline='$today'");
        if(!$db->affected_rows()) {
            $db->query("Insert INTO {$tablepre}modworks (uid, modaction, dateline, count, posts) VALUES ('$discuz_uid', '$modaction', '$today', 1, '$posts')");
        }
    }
}

//写入系统日志,$file 写入的日志文件,$log 要写入的内容提要

function writelog($file, $log) {
    global $timestamp, $_DCACHE;
    $yearmonth = gmdate('Ym', $timestamp + $_DCACHE['settings']['timeoffset'] * 3600);
    $logdir = DISCUZ_ROOT.'./forumdata/logs/';
    $logfile = $logdir.$yearmonth.'_'.$file.'.php';
    if(@filesize($logfile) > 2048000) {
        $dir = opendir($logdir);
        $length = strlen($file);
        $maxid = $id = 0;
        while($entry = readdir($dir)) {
            if(strexists($entry, $yearmonth.'_'.$file)) {
                $id = intval(substr($entry, $length + 8, -4));
                $id > $maxid && $maxid = $id;
            }
        }
        closedir($dir);

        $logfilebak = $logdir.$yearmonth.'_'.$file.'_'.($maxid + 1).'.php';
        @rename($logfile, $logfilebak);
    }
    if($fp = @fopen($logfile, 'a')) {
        @flock($fp, 2);
        $log = is_array($log) ? $log : array($log);
        foreach($log as $tmp) {
            fwrite($fp, "<?PHP exit;?>\t".str_replace(array('<?', '?>'), '', $tmp)."\n");
        }
        fclose($fp);
    }
}

//看成函数的重载,即把implode这个函数重载成在两边加上'(单引号)的函数
function implodeids($array) {
    if(!empty($array)) {
        return "'".implode("','", is_array($array) ? $array : array($array))."'";
    } else {
        return '';
    }
}

/**
* 把这三个函数放一起,因为它们三个是一起实现的,即传说中的ajax…
* 这里说一下ajax的实现方式,一种方法是用XMLHttpRequest异步提交给服务器,服务器返回一个带有数据结点的xml文件
* javascript或者php等解析这个xml文档,从而得到数据;另外一种是这个xml文件中含一个CDATA,把已经用HTML格式化好的
* 内容返回过来直接用,显然第二种好用,Discuz用的就是这样一个方式。其他用iframe等等就不在这里介绍了,那个一般
* 在提交数据检查、异步文件上传的时候用。
*/

//ajaxshowheader生成一个xml头和一个<root>根以及一个CDATA
function ajaxshowheader() {
    global $charset;
    @header("Expires: -1");
    @header("Cache-Control: no-store, private, post-check=0, pre-check=0, max-age=0", FALSE);
    @header("Pragma: no-cache");
    header("Content-type: application/xml");
    echo "<?xml version=\"1.0\" encoding=\"$charset\"?>\n<root><![CDATA[";
}

//闭合CDATA和root
function ajaxshowfooter() {
    echo ']]></root>';
}

//ajaxtemplate组合了ajaxshowheader + 模板 + ajaxshowfooter,使之完整。
function ajaxtemplate($tplname) {
    if(!empty($_GET['inajax'])) {
        extract($GLOBALS, EXTR_SKIP);
        updatesession();
        ajaxshowheader();
        include template($tplname);
        ajaxshowfooter();
        die();
    }
}

//过滤.., \n, \r 用的
function wipespecial($str) {
    return str_replace(array('..', "\n", "\r"), array('', '', ''), $str);
}

//supser site 数据库连接,通过$super['db']来用,而Discuz本身的是$db
function supe_dbconnect() {
    global $supe, $db;
    if(empty($supe['dbmode'])) {
        $supe['db'] = $db;
    } elseif(empty($supe['db'])) {
        $supe['db'] = new dbstuff;
        $supe['db']->connect($supe['dbhost'], $supe['dbuser'], $supe['dbpw'], $supe['dbname'], $supe['pconnect']);
    }
}

?>