1,
'_GET' => 1,
'_POST' => 1,
'_REQUEST' => 1,
'_COOKIE' => 1,
'_SERVER' => 1,
'_ENV' => 1,
'_FILES' => 1,
);
//建立唯一的进程
function &instance() {//单例模式实例化一个discuz_core核心类实例化对象
static $object;
if(empty($object)) {
$object = new discuz_core();//实例化一个discuz_core对象
}
return $object;//返回唯一的一个discuz_core类实例化对象
}
//预处理的调用
function discuz_core() {//构造函数
$this->_init_env();//初始化环境变量
$this->_init_config();//初始化配置变量
$this->_init_input();//初始化输入
$this->_init_output();//初始化输出
}
//核心的初始化
function init() {
if(!$this->initated) {
$this->_init_db();//数据库操作类实例化对象的初始化
$this->_init_memory();//初始化memcache
$this->_init_user();//用户信息初始化
$this->_init_session();//session操作初始化
$this->_init_setting();//系统设置初始化
$this->_init_mobile();//手机功能初始化
$this->_init_cron();//计划任务初始化
$this->_init_misc();//其他功能的初始化
}
$this->initated = true;//初始化完成的标志
}
//定义php环境信息常量和$_G全局变量
/*
* 1、主要讲$_G变量的引用赋值给$var数组变量
* 2、注意:G变量是程序的全局变量,为了让程序更加高效,减少不必要的数据获取,所以程序特将经常需要用到的变量统一到
* G变量下,如:用户登录信息、后台设置信息、服务器环境信息、客户端cookies、数据缓存等都存放在G变量里面,在制作
* 模板文件的时只需将G变量打印出来即可获得需要的信息是否在G变量中
* 3、自定义变量:自定义变量是以$开头并且首位为字母或下划线的变量,
* 如:$data、$thread、$post、$forumlist、$threadlist
* 4、类似$_G['gp_xxx']变量都是get和post过来的数据
*/
function _init_env() {
//设置错误级别
error_reporting(E_ERROR);
if(PHP_VERSION < '5.3.0') {
set_magic_quotes_runtime(0);//设置set_magic_quotes_runtime
}
define('DISCUZ_ROOT', substr(dirname(__FILE__), 0, -12));//定义根目录常量:"d:/wamp/www/discuz/"
define('MAGIC_QUOTES_GPC', function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc());//定义MAGIC_QUOTES_GPC常量
define('ICONV_ENABLE', function_exists('iconv'));//定义是否支持转码函数常量,如:iconv("gb2312","utf-8","我爱卡");//将gb2312编码转换为utf-8编码
define('MB_ENABLE', function_exists('mb_convert_encoding'));//定义是否支持转码函数常量,跟iconv用法差不多,有稍微差异
define('EXT_OBGZIP', function_exists('ob_gzhandler'));//缓存输出句柄函数
define('TIMESTAMP', time());//定义当前时间戳常量
$this->timezone_set();//设置时区
/*
* 1、加载系统核心函数库文件
* 2、条件:常量未定义、系统函数库未加载的情况下报"系统核心函数库文件丢失"的错误,否则加载系统核心函数库文件
*/
if(!defined('DISCUZ_CORE_FUNCTION') && !@include(DISCUZ_ROOT.'./source/function/function_core.php')) {
exit('function_core.php is missing');//退出,并报"系统核心函数库文件丢失的错误"
}
if(function_exists('ini_get')) {//获取php.ini配置文件中设置的配置信息
$memorylimit = @ini_get('memory_limit');//设置内存使用限制
if($memorylimit && return_bytes($memorylimit) < 33554432 && function_exists('ini_set')) {
ini_set('memory_limit', '128m');//如果小于32M,则增加到128M
}
}
define('IS_ROBOT', checkrobot());//检测机器人
//$GLOBALS:超全局变量,全局作用域中始终可用的内置变量,在函数和方法中无需使用 global $xxx声明
foreach ($GLOBALS as $key => $value) {
if (!isset($this->superglobal[$key])) {//注销没有在$superglobal中出现的超全局变量,也就是注销所有的超级全局变量
$GLOBALS[$key] = null; unset($GLOBALS[$key]);//设置为null并销毁
}
}
//超级变量大数组$_G的定义,在模板文件中要使用
global $_G;//函数体外可以使用,注意:只能在本文件中,或者include的文件中使用,并不能再整个网站中使用
$_G = array(
'uid' => 0,//作者UID
'username' => '',//用户名
'adminid' => 0,//管理组ID
'groupid' => 1,//用户组ID
'sid' => '',//cookie和session相关的sid
'formhash' => '',//表单验证认证
'timestamp' => TIMESTAMP,//时间戳
'starttime' => dmicrotime(),//开始时间
'clientip' => $this->_get_client_ip(),//客户端ip
'referer' => '',//来路
'charset' => '',//字符编码设置
'gzipcompress' => '',//gzip
'authkey' => '',//密钥
'timenow' => array(),
'PHP_SELF' => '',//当前php脚本文件,如:"/discuz/forum.php"
'siteurl' => '',//站点url
'siteroot' => '',//站点根目录
'siteport' => '',//站点端口
'config' => array(),//配置变量数组
'setting' => array(),//设置变量数组
'member' => array(),//用户信息数组
'group' => array(),//用户组数组
'cookie' => array(),//cookie数组
'style' => array(),//风格数组
'cache' => array(),//缓存列表数组
'session' => array(),//session变量数组
'lang' => array(),//语言包数组
'my_app' => array(),//我的应用数组
'my_userapp' => array(),//用户应用数组
'fid' => 0,//版块id
'tid' => 0,//帖子id
'forum' => array(),//论坛版块数组
'thread' => array(),//论坛相关帖子数组
'rssauth' => '',//RSS订阅认证
'home' => array(),//home功能相关数组
'space' => array(),//space功能相关数组
'block' => array(),//块信息数组
'article' => array(),//文章相关
'action' => array(
'action' => APPTYPEID,
'fid' => 0,//版块id
'tid' => 0,//帖子id
),
'mobile' => '',//手机信息
);
$_G['PHP_SELF'] = htmlspecialchars($this->_get_script_url());//将当前脚本地址写入$_G超级变量中;结果:"/discuz/forum.php"
$_G['basescript'] = CURSCRIPT;//当前不带扩展名的php脚本,如:"forum"
$_G['basefilename'] = basename($_G['PHP_SELF']);//显示带有文件扩展名的php文件名称,如:"forum.php"
$sitepath = substr($_G['PHP_SELF'], 0, strrpos($_G['PHP_SELF'], '/'));//如:"/discuz"
if(defined('IN_API')) {
$sitepath = preg_replace("/\/api\/?.*?$/i", '', $sitepath);
} elseif(defined('IN_ARCHIVER')) {
$sitepath = preg_replace("/\/archiver/i", '', $sitepath);
}
$_G['siteurl'] = htmlspecialchars('http://'.$_SERVER['HTTP_HOST'].$sitepath.'/');//网站地址
$url = parse_url($_G['siteurl']);
$_G['siteroot'] = isset($url['path']) ? $url['path'] : '';//网站根目录,如:"/discuz"
$_G['siteport'] = empty($_SERVER['SERVER_PORT']) || $_SERVER['SERVER_PORT'] == '80' ? '' : ':'.$_SERVER['SERVER_PORT'];//端口
if(defined('SUB_DIR')) {//二级目录设置情况
$_G['siteurl'] = str_replace(SUB_DIR, '/', $_G['siteurl']);
$_G['siteroot'] = str_replace(SUB_DIR, '/', $_G['siteroot']);
}
$this->var = & $_G;//$_G变量的引用赋值给$var,以后对$_G变量或$var变量的修改会直接影响到对方
}
/*
* 1、返回PHP_SELF当前脚本文件
*/
function _get_script_url() {
if($this->var['PHP_SELF'] === null){
$scriptName = basename($_SERVER['SCRIPT_FILENAME']);
if(basename($_SERVER['SCRIPT_NAME']) === $scriptName) {
$this->var['PHP_SELF'] = $_SERVER['SCRIPT_NAME'];
} else if(basename($_SERVER['PHP_SELF']) === $scriptName) {
$this->var['PHP_SELF'] = $_SERVER['PHP_SELF'];
} else if(isset($_SERVER['ORIG_SCRIPT_NAME']) && basename($_SERVER['ORIG_SCRIPT_NAME']) === $scriptName) {
$this->var['PHP_SELF'] = $_SERVER['ORIG_SCRIPT_NAME'];
} else if(($pos = strpos($_SERVER['PHP_SELF'],'/'.$scriptName)) !== false) {
$this->var['PHP_SELF'] = substr($_SERVER['SCRIPT_NAME'],0,$pos).'/'.$scriptName;
} else if(isset($_SERVER['DOCUMENT_ROOT']) && strpos($_SERVER['SCRIPT_FILENAME'],$_SERVER['DOCUMENT_ROOT']) === 0) {
$this->var['PHP_SELF'] = str_replace('\\','/',str_replace($_SERVER['DOCUMENT_ROOT'],'',$_SERVER['SCRIPT_FILENAME']));
} else {
system_error('request_tainting');
}
}
return $this->var['PHP_SELF'];
}
/*
* 1、合并$_POST和$_GET,然后将$_POST和$_GET的值都赋予gp变量中,方便使用
* 2、禁止对全局变量注入
* 3、slashes处理
* 4、cookie处理:去掉cookie前缀
*/
function _init_input() {
if (isset($_GET['GLOBALS']) ||isset($_POST['GLOBALS']) || isset($_COOKIE['GLOBALS']) || isset($_FILES['GLOBALS'])) {
system_error('request_tainting');//...请求中...
}
if(!MAGIC_QUOTES_GPC) {//魔术函数是否开启:仅仅对$_GET、$_POST、$_COOKIE起作用;主要用于在讲数据入库前做一些安全性的转义
$_GET = daddslashes($_GET);//对$_GET数据进行转义
$_POST = daddslashes($_POST);//对$_POST数据进行转义
$_COOKIE = daddslashes($_COOKIE);//对$_COOKIE数据进行转义
$_FILES = daddslashes($_FILES);//对$_FILES数据进行转义
}
/*
* 1、如果cookie的键值等于定义的键值,那么截取cookie的前缀cookiepre
*/
$prelength = strlen($this->config['cookie']['cookiepre']);
foreach($_COOKIE as $key => $val) {
if(substr($key, 0, $prelength) == $this->config['cookie']['cookiepre']) {
$this->var['cookie'][substr($key, $prelength)] = $val;//cookie赋值
}
}
/*
* 1、合并$_POST和$_GET,然后将$_POST和$_GET的值都赋予gp变量中,方便使用
*/
if($_SERVER['REQUEST_METHOD'] == 'POST' && !empty($_POST)) {
$_GET = array_merge($_GET, $_POST);
}
//diy
if(isset($_GET['diy'])) {
$_GET['diy'] = empty($_GET['diy']) ? '' : $_GET['diy'];
}
foreach($_GET as $k => $v) {
$this->var['gp_'.$k] = $v;//将$_POST和$_GET的值都赋予gp变量中,方便使用
}
//获取$mod变量,如:/?mod=xxx ,那么$this->var['mod']=xxx;
$this->var['mod'] = empty($this->var['gp_mod']) ? '' : htmlspecialchars($this->var['gp_mod']);
//是否需要ajax方式
$this->var['inajax'] = empty($this->var['gp_inajax']) ? 0 : (empty($this->var['config']['output']['ajaxvalidate']) ? 1 : ($_SERVER['REQUEST_METHOD'] == 'GET' && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' || $_SERVER['REQUEST_METHOD'] == 'POST' ? 1 : 0));
//页面获取,最小为1
$this->var['page'] = empty($this->var['gp_page']) ? 1 : max(1, intval($this->var['gp_page']));
//cookie与session相关的sid的获取
$this->var['sid'] = $this->var['cookie']['sid'] = isset($this->var['cookie']['sid']) ? htmlspecialchars($this->var['cookie']['sid']) : '';
$this->var['gp_handlekey'] = !empty($this->var['gp_handlekey']) && preg_match('/^\w+$/', $this->var['gp_handlekey']) ? $this->var['gp_handlekey'] : '';
if(empty($this->var['cookie']['saltkey'])) {//解密时可能会使用到
$this->var['cookie']['saltkey'] = random(8);
dsetcookie('saltkey', $this->var['cookie']['saltkey'], 86400 * 30, 1, 1);
}
//密钥
$this->var['authkey'] = md5($this->var['config']['security']['authkey'].$this->var['cookie']['saltkey']);
}
/*
* 1、主要讲$config引用赋值给$config=array()和 $var['config']=$config;
* 2、加载配置文件
*/
function _init_config() {
$_config = array();//定义$_config配置数组
@include DISCUZ_ROOT.'./config/config_global.php';//加载全局配置文件,配置文件中是一个$_config数组
if(empty($_config)) {//配置信息为空的情况,安装前为空
if(!file_exists(DISCUZ_ROOT.'./data/install.lock')) {//没有安装的情况
header('location: install');//安装discuz论坛系统
exit;
} else {
system_error('config_notfound');
}
}
//设置安全认证的authkey
if(empty($_config['security']['authkey'])) {
$_config['security']['authkey'] = md5($_config['cookie']['cookiepre'].$_config['db'][1]['dbname']);//密钥的组成:cookie前缀+数据库的名称
}
//是否调试模式
if(empty($_config['debug']) || !file_exists(libfile('function/debug'))) {
define('DISCUZ_DEBUG', false);//调试模式关闭
} elseif($_config['debug'] === 1 || $_config['debug'] === 2 || !empty($_REQUEST['debug']) && $_REQUEST['debug'] === $_config['debug']) {
define('DISCUZ_DEBUG', true);//调试模式打开
if($_config['debug'] == 2) {
error_reporting(E_ALL);//设置错误级别
}
} else {
define('DISCUZ_DEBUG', false);
}
//定义静态文件常量:方便找到images、css、js素材文件
define('STATICURL', !empty($_config['output']['staticurl']) ? $_config['output']['staticurl'] : 'static/');
$this->var['staticurl'] = STATICURL;//素材文件url:主要用于存储images、css、js等素材文件
$this->config = & $_config;//配置信息的引用赋值给$config数组变量
$this->var['config'] = & $_config;//同时配置信息的引用赋值给$var['config'],即:赋值给了$_G['config']
//设置cookie域,一般是设置目录域,"/"不存在则加上"/"
if(substr($_config['cookie']['cookiepath'], 0, 1) != '/') {//cookie路径
$this->var['config']['cookie']['cookiepath'] = '/'.$this->var['config']['cookie']['cookiepath'];
}
//定义cookie前缀,如:定义为xxx_,则为$cookie[xxx_uid]
$this->var['config']['cookie']['cookiepre'] = $this->var['config']['cookie']['cookiepre'].substr(md5($this->var['config']['cookie']['cookiepath'].'|'.$this->var['config']['cookie']['cookiedomain']), 0, 4).'_';
}
/*
* 1、输出处理
* 2、get参数跨站检测
* 3、防页面刷新
* 4、gzip处理
* 5、字符集处理
*/
function _init_output() {
if($this->config['security']['urlxssdefend'] && $_SERVER['REQUEST_METHOD'] == 'GET' && !empty($_SERVER['REQUEST_URI'])) {
$this->_xss_check();
}
/*
* 1、验证码的设置:加载include/misc/security.php文件,验证功能
*/
if($this->config['security']['attackevasive'] && (!defined('CURSCRIPT') || !in_array($this->var['mod'], array('seccode', 'secqaa', 'swfupload')))) {
require_once libfile('misc/security', 'include');
}
/*
* 1、是否开启gzip,如果不支持gzip,则定义为false
*/
if(!empty($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') === false) {
$this->config['output']['gzip'] = false;
}
//将$allowgzip写入全局变量中
$allowgzip = $this->config['output']['gzip'] && empty($this->var['inajax']) && $this->var['mod'] != 'attachment' && EXT_OBGZIP;
setglobal('gzipcompress', $allowgzip);
ob_start($allowgzip ? 'ob_gzhandler' : null);//定义输出缓存
//将配置文件中的字符集写入全局变量中
setglobal('charset', $this->config['output']['charset']);
define('CHARSET', $this->config['output']['charset']);
if($this->config['output']['forceheader']) {
@header('Content-Type: text/html; charset='.CHARSET);//设置网页编码,强制输出
}
}
/*
* 1、拒绝机器人访问,设置为403错误
*/
function reject_robot() {
if(IS_ROBOT) {
exit(header("HTTP/1.1 403 Forbidden"));
}
}
/*
* 1、检查xss漏洞、ubb漏洞
* 2、get参数跨站检测
*/
function _xss_check() {
$temp = strtoupper(urldecode(urldecode($_SERVER['REQUEST_URI'])));
if(strpos($temp, '<') !== false || strpos($temp, '"') !== false || strpos($temp, 'CONTENT-TRANSFER-ENCODING') !== false) {
system_error('request_tainting');
}
return true;
}
/*
* 1、获取客户端的ip
*/
function _get_client_ip() {
$ip = $_SERVER['REMOTE_ADDR'];
if (isset($_SERVER['HTTP_CLIENT_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif(isset($_SERVER['HTTP_X_FORWARDED_FOR']) AND preg_match_all('#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#s', $_SERVER['HTTP_X_FORWARDED_FOR'], $matches)) {
foreach ($matches[0] AS $xip) {
if (!preg_match('#^(10|172\.16|192\.168)\.#', $xip)) {
$ip = $xip;
break;
}
}
}
return $ip;
}
/*
* 1、初始化数据库类、同时选择主从数据库
*/
function _init_db() {
$class = 'db_mysql';
if(count(getglobal('config/db/slave'))) {//是否存在从数据连接,存在则初始化
require_once libfile('class/mysql_slave');
$class = 'db_mysql_slave';
}
$this->db = & DB::object($class);
$this->db->set_config($this->config['db']);
$this->db->connect();//建立数据库连接
}
/*
* 1、初始化session信息
*/
function _init_session() {
$this->session = new discuz_session();
if($this->init_session) {
$this->session->init($this->var['cookie']['sid'], $this->var['clientip'], $this->var['uid']);
$this->var['sid'] = $this->session->sid;//设置sid
$this->var['session'] = $this->session->var;//设置session
if($this->var['sid'] != $this->var['cookie']['sid']) {
dsetcookie('sid', $this->var['sid'], 86400);//如果sid不为cookie中的sid,则重写sid到cookie
}
if($this->session->isnew) {
if(ipbanned($this->var['clientip'])) {//如果发现ip在禁止范围内,则设置该客户端用户组为6,即:禁止ip用户组
$this->session->set('groupid', 6);
}
}
if($this->session->get('groupid') == 6) {
$this->var['member']['groupid'] = 6;
sysmessage('user_banned');//提示ip禁止
}
/*
* 1、最近活动检测,600秒
*/
if($this->var['uid'] && ($this->session->isnew || ($this->session->get('lastactivity') + 600) < TIMESTAMP)) {
$this->session->set('lastactivity', TIMESTAMP);
if($this->session->isnew) {
//如果用户在600秒内不活动,则设置最后访问时间点
DB::update('common_member_status', array('lastip' => $this->var['clientip'], 'lastvisit' => TIMESTAMP), "uid='".$this->var['uid']."'");
}
}
}
}
/*
* 1、初始化当前用户信息
*/
function _init_user() {
if($this->init_user) {
$discuz_uid = '';
/*通过COOKIE取得用户信息 start*/
/*TODO utf-8 2 GBK change start*/
/*$_cookie_userName = $_COOKIE["USERNAME"];*/
$username_tmp = $_COOKIE["USERNAME"];
$a=urldecode($username_tmp);
/*$a=mb_convert_encoding($a, 'GB2312', 'UTF-8'); */
$a=diconv($a, 'UTF-8', 'GBK');
$_cookie_userName = $a;
/*TODO utf-8 2 GBK change start*/
$_cookie_userPassWord = $_COOKIE["USERAUTHCODE"];
/*通过COOKIE取得用户信息 end*/
if(!empty($_cookie_userName) && !empty($_cookie_userPassWord)) {
/* 判断用户是不是在UCENTER中存在,如果不存在则插入一条数据同步到DIS论坛用户 START */
/* 用COOKIE用户名称检索UCENTER */
$query = DB::query("SELECT uid FROM ".DB::table('ucenter_members')." WHERE username = '$_cookie_userName' limit 1");
if(!DB::num_rows($query)) {
// 插入用户中心数据
DB::query( "INSERT INTO ".DB::table('ucenter_members')." (uid,username,password,email) VALUES ('$discuz_uid','$_cookie_userName','$_cookie_userPassWord','')");
DB::query("commit;");
$query = DB::query("SELECT uid FROM ".DB::table('ucenter_members')." WHERE username = '$_cookie_userName' limit 1");
$discuz_uid = DB::result($query, 0);
DB::query( "INSERT INTO ".DB::table('ucenter_memberfields')."(uid) VALUES ('$discuz_uid')");
DB::query("commit;");
/* 这个取得公用主键ID 创建UCENTER中用户,在DIS中再检索处理 */
/* 取得论坛用户UID */
$query = DB::query("SELECT uid FROM ".DB::table("common_member")." WHERE username = '$_cookie_userName' limit 1");
if(DB::num_rows($query)) {
$discuz_uid = DB::result($query, 0);
} else {
// 同步插入论坛数据
DB::query( "INSERT INTO ".DB::table('common_member')." (uid,username,password,adminid,groupid,regdate,email) VALUES ('$discuz_uid','$_cookie_userName','$_cookie_userPassWord','0','10','1307062876','')");
DB::query( "INSERT INTO ".DB::table('common_member_status')." (uid) VALUES ('$discuz_uid')");
DB::query( "INSERT INTO ".DB::table('common_member_profile')."(uid)value('$discuz_uid')");
DB::query( "INSERT INTO ".DB::table('common_member_field_forum')."(uid)value('$discuz_uid')");
DB::query( "INSERT INTO ".DB::table('common_member_field_home')."(uid)VALUE('$discuz_uid')");
DB::query( "INSERT INTO ".DB::table('common_member_count')."(uid,extcredits1,extcredits2,extcredits3,extcredits4,extcredits5,extcredits6,extcredits7,extcredits8)VALUE('$discuz_uid','0','0','0','0','0','0','0','0')");
DB::query("commit;");
$query = DB::query("SELECT uid FROM ".DB::table("common_member")." WHERE username = '$_cookie_userName' limit 1");
$discuz_uid = DB::result($query, 0);
}
// 取得登录用户信息,写入COOKIE
$user = getuserbyuid($discuz_uid);
$ucsynlogin = $this->setting['allowsynlogin'] ? uc_user_synlogin($discuz_uid) : '';
$this->var['member'] = $user;
} else {
// 取得登录用户信息,写入COOKIE
$discuz_uid = DB::result($query, 0);
DB::query(" UPDATE ".DB::table('ucenter_members')." SET password='".$_cookie_userPassWord."' WHERE uid=".$discuz_uid);
DB::query(" UPDATE ".DB::table('common_member')." SET password='".$_cookie_userPassWord."' WHERE uid=".$discuz_uid);
DB::query("commit;");
$user = getuserbyuid($discuz_uid);
//var_dump($discuz_uid);
$ucsynlogin = $this->setting['allowsynlogin'] ? uc_user_synlogin($discuz_uid) : '';
//var_dump($ucsynlogin);
$this->var['member'] = $user;
}
/*判断用户是不是在UCENTER中存在,如果不存在则插入一条数据同步到DIS论坛用户 END */
} else {
/*判断是否UC用户 来源CDB start*/
if($auth = getglobal('auth', 'cookie')) {//得到auth,auth的值:"username\tuid"的加密信息
//进行解密
$auth = daddslashes(explode("\t", authcode($auth, 'DECODE')));
}
//得到用户名和用户密码,如果auth为空,或者确实uid和username中的一个,则为空
list($discuz_pw, $discuz_uid) = empty($auth) || count($auth) < 2 ? array('', '') : $auth;
if($discuz_uid) {
$user = getuserbyuid($discuz_uid);//如果uid存在,则得到该用户信息
}
if(!empty($user) && $user['password'] == $discuz_pw) {
$this->var['member'] = $user;//如果用户存在且密码正确,则将用户信息写入全局变量中
} else {
/*游客判断 START*/
$user = array();//user定义为空数组
$this->_init_guest();//是否为游客,游客初始化方法
/*游客判断 END*/
}
/*判断是否UC用户 来源CDB end*/
}
//用户组过期检测
if($user && $user['groupexpiry'] > 0 && $user['groupexpiry'] < TIMESTAMP && getgpc('mod') != 'spacecp' && getgpc('do') != 'expiry' && CURSCRIPT != 'home') {
dheader('location: home.php?mod=spacecp&ac=usergroup&do=expiry');
}
//用户组数据缓存
$this->cachelist[] = 'usergroup_'.$this->var['member']['groupid'];
if($user && $user['adminid'] > 0 && $user['groupid'] != $user['adminid']) {
$this->cachelist[] = 'admingroup_'.$this->var['member']['adminid'];
}
} else {
$this->_init_guest();//游客
}
if(empty($this->var['cookie']['lastvisit'])) {//cookie中如果记录有最后一次访问时间,则写入
$this->var['member']['lastvisit'] = TIMESTAMP - 3600;
dsetcookie('lastvisit', TIMESTAMP - 3600, 86400 * 30);
} else {
//否则写入全局变量
$this->var['member']['lastvisit'] = $this->var['cookie']['lastvisit'];
}
setglobal('uid', getglobal('uid', 'member'));//用户uid
setglobal('username', addslashes(getglobal('username', 'member')));//用户名
setglobal('adminid', getglobal('adminid', 'member'));//管理组id
setglobal('groupid', getglobal('groupid', 'member'));//用户组id
}
/*
* 1、初始化当前用户信息为游客
*/
function _init_guest() {
setglobal('member', array( 'uid' => 0, 'username' => '', 'adminid' => 0, 'groupid' => 7, 'credits' => 0, 'timeoffset' => 9999));
}
/*
* 1、处理计划任务
*/
function _init_cron() {
$ext = empty($this->config['remote']['on']) || empty($this->config['remote']['cron']) || APPTYPEID == 200;
if($this->init_cron && $this->init_setting && $ext) {
if($this->var['cache']['cronnextrun'] <= TIMESTAMP) {
require_once libfile('class/cron');//加载"/source/class/class_cron.php"文件
discuz_cron::run();//运行
}
}
}
/*
* 1、杂项
* 2、调入核心语言包
* 3、处理全局时区设置
* 4、处理被封禁用户
* 5、站点开关检查
* 6、手机端控制每页显示主题数和回帖数
* 7、判断并执行每日登陆奖励积分
*/
function _init_misc() {
if(!$this->init_misc) {
return false;
}
lang('core');//加载core语言包
//设置用户时区
if($this->init_setting && $this->init_user) {
if(!isset($this->var['member']['timeoffset']) || $this->var['member']['timeoffset'] == 9999 || $this->var['member']['timeoffset'] === '') {
$this->var['member']['timeoffset'] = $this->var['setting']['timeoffset'];
}
}
$timeoffset = $this->init_setting ? $this->var['member']['timeoffset'] : $this->var['setting']['timeoffset'];
$this->var['timenow'] = array(
'time' => dgmdate(TIMESTAMP),
'offset' => $timeoffset >= 0 ? ($timeoffset == 0 ? '' : '+'.$timeoffset) : $timeoffset
);
$this->timezone_set($timeoffset);
$this->var['formhash'] = formhash();//得到formhash
define('FORMHASH', $this->var['formhash']);//定义为常量
if($this->init_user) {
if($this->var['group'] && isset($this->var['group']['allowvisit']) && !$this->var['group']['allowvisit']) {
if($this->var['uid']) {
sysmessage('user_banned', null);//检测是否为禁止访问
} elseif((!defined('ALLOWGUEST') || !ALLOWGUEST) && !in_array(CURSCRIPT, array('member', 'api')) && !$this->var['inajax']) {
dheader('location: member.php?mod=logging&action=login&referer='.rawurlencode($_SERVER['REQUEST_URI']));
}
}
if($this->var['member']['status'] == -1) {
sysmessage('user_banned', null);//如果用户状态为-1,则提示禁止访问
}
}
if($this->var['setting']['ipaccess'] && !ipaccess($this->var['clientip'], $this->var['setting']['ipaccess'])) {
sysmessage('user_banned', null);//ip权限检测
}
//如果论坛为关闭,只有管理员可以访问,其他则提示关闭原因
if($this->var['setting']['bbclosed']) {
if($this->var['uid'] && ($this->var['group']['allowvisit'] == 2 || $this->var['groupid'] == 1)) {
} elseif(in_array(CURSCRIPT, array('admin', 'member', 'api')) || defined('ALLOWGUEST') && ALLOWGUEST) {
} else {
$closedreason = DB::result_first("SELECT svalue FROM ".DB::table('common_setting')." WHERE skey='closedreason'");
$closedreason = str_replace(':', ':', $closedreason);
showmessage($closedreason ? $closedreason : 'board_closed', NULL, array('adminemail' => $this->var['setting']['adminemail']), array('login' => 1));
}
}
if(CURSCRIPT != 'admin' && !(in_array($this->var['mod'], array('logging', 'seccode')))) {
periodscheck('visitbanperiods');//私密板块访问设置
}
//wap访问设置
if(defined('IN_MOBILE')) {
$this->var['tpp'] = $this->var['setting']['mobile']['mobiletopicperpage'] ? intval($this->var['setting']['mobile']['mobiletopicperpage']) : 20;
$this->var['ppp'] = $this->var['setting']['mobile']['mobilepostperpage'] ? intval($this->var['setting']['mobile']['mobilepostperpage']) : 5;
} else {
$this->var['tpp'] = $this->var['setting']['topicperpage'] ? intval($this->var['setting']['topicperpage']) : 20;
$this->var['ppp'] = $this->var['setting']['postperpage'] ? intval($this->var['setting']['postperpage']) : 10;
}
//header头信息设置
if($this->var['setting']['nocacheheaders']) {
@header("Expires: -1");
@header("Cache-Control: no-store, private, post-check=0, pre-check=0, max-age=0", FALSE);
@header("Pragma: no-cache");
}
if($this->session->isnew && $this->var['uid']) {
updatecreditbyaction('daylogin', $this->var['uid']);//每日登陆增加积分设置
include_once libfile('function/stat');
updatestat('login', 1);
if(defined('IN_MOBILE')) {
updatestat('mobilelogin', 1);
}
if($this->var['setting']['connect']['allow'] && $this->var['member']['conisbind']) {
updatestat('connectlogin', 1);
}
}
if($this->var['member']['conisbind'] && $this->var['setting']['connect']['newbiespan'] !== '') {
$this->var['setting']['newbiespan'] = $this->var['setting']['connect']['newbiespan'];
}
$lastact = TIMESTAMP."\t".htmlspecialchars(basename($this->var['PHP_SELF']))."\t".htmlspecialchars($this->var['mod']);
dsetcookie('lastact', $lastact, 86400);
setglobal('currenturl_encode', base64_encode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']));
if((!empty($this->var['gp_fromuid']) || !empty($this->var['gp_fromuser'])) && ($this->var['setting']['creditspolicy']['promotion_visit'] || $this->var['setting']['creditspolicy']['promotion_register'])) {
require_once libfile('misc/promotion', 'include');
}
//SEO关键词、描述
$this->var['seokeywords'] = !empty($this->var['setting']['seokeywords'][CURSCRIPT]) ? $this->var['setting']['seokeywords'][CURSCRIPT] : '';
$this->var['seodescription'] = !empty($this->var['setting']['seodescription'][CURSCRIPT]) ? $this->var['setting']['seodescription'][CURSCRIPT] : '';
}
/*
* 1、加载全局设置 setting 、风格 style 、 下一个任务 cronnextrun
*/
function _init_setting() {
if($this->init_setting) {
if(empty($this->var['setting'])) {
$this->cachelist[] = 'setting';//缓存设置文件
}
if(empty($this->var['style'])) {
$this->cachelist[] = 'style_default';//风格缓存设置
}
if(!isset($this->var['cache']['cronnextrun'])) {
$this->cachelist[] = 'cronnextrun';//缓存计划任务
}
}
!empty($this->cachelist) && loadcache($this->cachelist);
if(!is_array($this->var['setting'])) {
$this->var['setting'] = array();
}
if($this->var['member'] && $this->var['group']['radminid'] == 0 && $this->var['member']['adminid'] > 0 && $this->var['member']['groupid'] != $this->var['member']['adminid'] && !empty($this->var['cache']['admingroup_'.$this->var['member']['adminid']])) {
$this->var['group'] = array_merge($this->var['group'], $this->var['cache']['admingroup_'.$this->var['member']['adminid']]);
}
}
/*
* 1、处理当前界面风格
* 2、定义风格常量
*/
function _init_style() {
$styleid = !empty($this->var['cookie']['styleid']) ? $this->var['cookie']['styleid'] : 0;
if(intval(!empty($this->var['forum']['styleid']))) {
$this->var['cache']['style_default']['styleid'] = $styleid = $this->var['forum']['styleid'];
} elseif(intval(!empty($this->var['category']['styleid']))) {
$this->var['cache']['style_default']['styleid'] = $styleid = $this->var['category']['styleid'];
}
$styleid = intval($styleid);
if($styleid && $styleid != $this->var['setting']['styleid']) {
loadcache('style_'.$styleid);
if($this->var['cache']['style_'.$styleid]) {
$this->var['style'] = $this->var['cache']['style_'.$styleid];
}
}
define('IMGDIR', $this->var['style']['imgdir']);
define('STYLEID', $this->var['style']['styleid']);
define('VERHASH', $this->var['style']['verhash']);
define('TPLDIR', $this->var['style']['tpldir']);
define('TEMPLATEID', $this->var['style']['templateid']);
}
//初始化discuz内存读写引擎
function _init_memory() {
$this->mem = new discuz_memory();
if($this->init_memory) {
$this->mem->init($this->config['memory']);
}
$this->var['memory'] = $this->mem->type;
}
//手机访问设置
function _init_mobile() {
if(!$this->var['setting'] || !$this->init_mobile || !$this->var['setting']['mobile']['allowmobile'] || !is_array($this->var['setting']['mobile']) || IS_ROBOT) {
$nomobile = true;//允许手机访问
$unallowmobile = true;
}
if($_GET['mobile'] === 'no') {
dsetcookie('mobile', 'no', 3600);
$nomobile = true;
} elseif($this->var['cookie']['mobile'] == 'no' && $_GET['mobile'] === 'yes') {
dsetcookie('mobile', '');
} elseif($this->var['cookie']['mobile'] == 'no') {
$nomobile = true;
}
if(!checkmobile()) {//检测是否为手机访问
$nomobile = true;
}
if($this->var['setting']['mobile']['mobilepreview'] && !$this->var['mobile'] && !$unallowmobile) {
if($_GET['mobile'] === 'yes') {
dheader("Location:misc.php?mod=mobile");
}
}
if($nomobile || (!$this->var['setting']['mobile']['mobileforward'] && $_GET['mobile'] !== 'yes')) {
if($_SERVER['HTTP_HOST'] == $this->var['setting']['domain']['app']['mobile'] && $this->var['setting']['domain']['app']['default']) {
dheader("Location:http://".$this->var['setting']['domain']['app']['default'].$_SERVER['REQUEST_URI']);
} else {
return;
}
}
if(strpos($this->var['setting']['domain']['defaultindex'], CURSCRIPT) !== false && CURSCRIPT != 'forum' && !$_GET['mod']) {
if($this->var['setting']['domain']['app']['mobile']) {
$mobileurl = 'http://'.$this->var['setting']['domain']['app']['mobile'];
} else {
if($this->var['setting']['domain']['app']['forum']) {
$mobileurl = 'http://'.$this->var['setting']['domain']['app']['forum'].'?mobile=yes';
} else {
$mobileurl = $this->var['siteurl'].'forum.php?mobile=yes';
}
}
dheader("location:$mobileurl");
}
define('IN_MOBILE', true);
setglobal('gzipcompress', 0);
$arr = array(strstr($_SERVER['QUERY_STRING'], '&simpletype'), strstr($_SERVER['QUERY_STRING'], 'simpletype'), '&mobile=yes', 'mobile=yes');
$query_sting_tmp = str_replace($arr, '', $_SERVER['QUERY_STRING']);
$this->var['setting']['mobile']['nomobileurl'] = ($this->var['setting']['domain']['app']['forum'] ? 'http://'.$this->var['setting']['domain']['app']['forum'].'/' : $this->var['siteurl']).$this->var['basefilename'].($query_sting_tmp ? '?'.$query_sting_tmp.'&' : '?').'mobile=no';
$this->var['setting']['lazyload'] = 0;
if('utf-8' != CHARSET) {
if(strtolower($_SERVER['REQUEST_METHOD']) === 'post') {
foreach($_POST AS $pk => $pv) {
if(!is_numeric($pv)) {
$this->var['gp_'.$pk] = $_GET[$pk] = $_POST[$pk] = $this->mobile_iconv_recurrence($pv);
}
}
}
}
if($_GET['simpletype']) {
if($_GET['simpletype'] == 'yes') {
$this->var['setting']['mobile']['mobilesimpletype'] = 1;
dsetcookie('simpletype', 1, 86400);
} else {
$this->var['setting']['mobile']['mobilesimpletype'] = 0;
dsetcookie('simpletype', 0, 86400);
}
} elseif($this->var['cookie']['simpletype']) {
$this->var['setting']['mobile']['mobilesimpletype'] = $this->var['cookie']['simpletype'] == 1 ? 1 : 0 ;
}
if(!$this->var['setting']['mobile']['mobilesimpletype']) {
$this->var['setting']['imagemaxwidth'] = 224;
}
$this->var['setting']['regstatus'] = $this->var['setting']['mobile']['mobileregister'] ? $this->var['setting']['regstatus'] : 0 ;
if(!$this->var['setting']['mobile']['mobileseccode']) {
$this->var['setting']['seccodestatus'] = 0;
}
$this->var['setting']['seccodedata']['type'] = 99;
$this->var['setting']['thumbquality'] = 50;
$this->var['setting']['mobile']['simpletypeurl'] = array();
$this->var['setting']['mobile']['simpletypeurl'][0] = $this->var['siteurl'].$this->var['basefilename'].($query_sting_tmp ? '?'.$query_sting_tmp.'&' : '?').'mobile=yes&simpletype=no';
$this->var['setting']['mobile']['simpletypeurl'][1] = $this->var['siteurl'].$this->var['basefilename'].($query_sting_tmp ? '?'.$query_sting_tmp.'&' : '?').'mobile=yes&simpletype=yes';
unset($query_sting_tmp);
ob_start();
}
//时区设置
function timezone_set($timeoffset = 0) {
if(function_exists('date_default_timezone_set')) {
@date_default_timezone_set('Etc/GMT'.($timeoffset > 0 ? '-' : '+').(abs($timeoffset)));
}
}
//手机访问再次转码
function mobile_iconv_recurrence($value) {
if(is_array($value)) {
foreach($value AS $key => $val) {
$value[$key] = $this->mobile_iconv_recurrence($val);
}
} else {
$value = addslashes(diconv(stripslashes($value), 'utf-8', CHARSET));
}
return $value;
}
}
/**
* Discuz MySQL 类的支持 程序中不直接使用
*
*/
class db_mysql
{
var $tablepre;
var $version = '';
var $querynum = 0;
var $slaveid = 0;
var $curlink;
var $link = array();
var $config = array();
var $sqldebug = array();
var $map = array();
function db_mysql($config = array()) {
if(!empty($config)) {
$this->set_config($config);
}
}
function set_config($config) {
$this->config = &$config;
$this->tablepre = $config['1']['tablepre'];
if(!empty($this->config['map'])) {
$this->map = $this->config['map'];
}
}
function connect($serverid = 1) {
if(empty($this->config) || empty($this->config[$serverid])) {
$this->halt('config_db_not_found');
}
$this->link[$serverid] = $this->_dbconnect(
$this->config[$serverid]['dbhost'],
$this->config[$serverid]['dbuser'],
$this->config[$serverid]['dbpw'],
$this->config[$serverid]['dbcharset'],
$this->config[$serverid]['dbname'],
$this->config[$serverid]['pconnect']
);
$this->curlink = $this->link[$serverid];
}
function _dbconnect($dbhost, $dbuser, $dbpw, $dbcharset, $dbname, $pconnect) {
$link = null;
$func = empty($pconnect) ? 'mysql_connect' : 'mysql_pconnect';
if(!$link = @$func($dbhost, $dbuser, $dbpw, 1)) {
$this->halt('notconnect');
} else {
$this->curlink = $link;
if($this->version() > '4.1') {
$dbcharset = $dbcharset ? $dbcharset : $this->config[1]['dbcharset'];
$serverset = $dbcharset ? 'character_set_connection='.$dbcharset.', character_set_results='.$dbcharset.', character_set_client=binary' : '';
$serverset .= $this->version() > '5.0.1' ? ((empty($serverset) ? '' : ',').'sql_mode=\'\'') : '';
$serverset && mysql_query("SET $serverset", $link);
}
$dbname && @mysql_select_db($dbname, $link);
}
return $link;
}
function table_name($tablename) {
if(!empty($this->map) && !empty($this->map[$tablename])) {
$id = $this->map[$tablename];
if(!$this->link[$id]) {
$this->connect($id);
}
$this->curlink = $this->link[$id];
return $this->config[$id]['tablepre'].$tablename;
} else {
$this->curlink = $this->link[1];
}
return $this->tablepre.$tablename;
}
function select_db($dbname) {
return mysql_select_db($dbname, $this->curlink);
}
function fetch_array($query, $result_type = MYSQL_ASSOC) {
return mysql_fetch_array($query, $result_type);
}
function fetch_first($sql) {
return $this->fetch_array($this->query($sql));
}
function result_first($sql) {
return $this->result($this->query($sql), 0);
}
function query($sql, $type = '') {
if(defined('DISCUZ_DEBUG') && DISCUZ_DEBUG) {
$starttime = dmicrotime();
}
$func = $type == 'UNBUFFERED' && @function_exists('mysql_unbuffered_query') ?
'mysql_unbuffered_query' : 'mysql_query';
if(!($query = $func($sql, $this->curlink))) {
if(in_array($this->errno(), array(2006, 2013)) && substr($type, 0, 5) != 'RETRY') {
$this->connect();
return $this->query($sql, 'RETRY'.$type);
}
if($type != 'SILENT' && substr($type, 5) != 'SILENT') {
$this->halt('query_error', $sql);
}
}
if(defined('DISCUZ_DEBUG') && DISCUZ_DEBUG) {
$this->sqldebug[] = array($sql, number_format((dmicrotime() - $starttime), 6), debug_backtrace());
}
$this->querynum++;
return $query;
}
function affected_rows() {
return mysql_affected_rows($this->curlink);
}
function error() {
return (($this->curlink) ? mysql_error($this->curlink) : mysql_error());
}
function errno() {
return intval(($this->curlink) ? mysql_errno($this->curlink) : mysql_errno());
}
function result($query, $row = 0) {
$query = @mysql_result($query, $row);
return $query;
}
function num_rows($query) {
$query = mysql_num_rows($query);
return $query;
}
function num_fields($query) {
return mysql_num_fields($query);
}
function free_result($query) {
return mysql_free_result($query);
}
function insert_id() {
return ($id = mysql_insert_id($this->curlink)) >= 0 ? $id : $this->result($this->query("SELECT last_insert_id()"), 0);
}
function fetch_row($query) {
$query = mysql_fetch_row($query);
return $query;
}
function fetch_fields($query) {
return mysql_fetch_field($query);
}
function version() {
if(empty($this->version)) {
$this->version = mysql_get_server_info($this->curlink);
}
return $this->version;
}
function close() {
return mysql_close($this->curlink);
}
function halt($message = '', $sql = '') {
require_once libfile('class/error');
discuz_error::db_error($message, $sql);
}
}
/**
* 对Discuz CORE 中 DB Object中的主要方法进行二次封装,方便程序调用
*
*/
class DB
{
/**
* 返回表名(pre_$table)
*
* @param 原始表名 $table
* @return 增加pre之后的名字
*/
function table($table) {
return DB::_execute('table_name', $table);
}
/**
* 删除一条或者多条记录
*
* @param string $table 原始表名
* @param string $condition 条件语句,不需要写WHERE
* @param int $limit 删除条目数
* @param boolean $unbuffered 立即返回?
*/
function delete($table, $condition, $limit = 0, $unbuffered = true) {
if(empty($condition)) {
$where = '1';
} elseif(is_array($condition)) {
$where = DB::implode_field_value($condition, ' AND ');
} else {
$where = $condition;
}
$sql = "DELETE FROM ".DB::table($table)." WHERE $where ".($limit ? "LIMIT $limit" : '');
return DB::query($sql, ($unbuffered ? 'UNBUFFERED' : ''));
}
/**
* 插入一条记录
*
* @param string $table 原始表名
* @param array $data 数组field->vlaue 对
* @param boolen $return_insert_id 返回 InsertID?
* @param boolen $replace 是否是REPLACE模式
* @param boolen $silent 屏蔽错误?
* @return InsertID or Result
*/
function insert($table, $data, $return_insert_id = false, $replace = false, $silent = false) {
$sql = DB::implode_field_value($data);
$cmd = $replace ? 'REPLACE INTO' : 'INSERT INTO';
$table = DB::table($table);
$silent = $silent ? 'SILENT' : '';
$return = DB::query("$cmd $table SET $sql", $silent);
return $return_insert_id ? DB::insert_id() : $return;
}
/**
* 更新一条或者多条数据记录
*
* @param string $table 原始表名
* @param array $data 数据field-value
* @param string $condition 条件语句,不需要写WHERE
* @param boolean $unbuffered 迅速返回?
* @param boolan $low_priority 延迟更新?
* @return result
*/
function update($table, $data, $condition, $unbuffered = false, $low_priority = false) {
$sql = DB::implode_field_value($data);
$cmd = "UPDATE ".($low_priority ? 'LOW_PRIORITY' : '');
$table = DB::table($table);
$where = '';
if(empty($condition)) {
$where = '1';
} elseif(is_array($condition)) {
$where = DB::implode_field_value($condition, ' AND ');
} else {
$where = $condition;
}
$res = DB::query("$cmd $table SET $sql WHERE $where", $unbuffered ? 'UNBUFFERED' : '');
return $res;
}
/**
* 格式化field字段和value,并组成一个字符串
*
* @param array $array 格式为 key=>value 数组
* @param 分割符 $glue
* @return string
*/
function implode_field_value($array, $glue = ',') {
$sql = $comma = '';
foreach ($array as $k => $v) {
$sql .= $comma."`$k`='$v'";
$comma = $glue;
}
return $sql;
}
/**
* 返回插入的ID
*
* @return int
*/
function insert_id() {
return DB::_execute('insert_id');
}
/**
* 依据查询结果,返回一行数据
*
* @param resourceID $resourceid
* @return array
*/
function fetch($resourceid, $type = MYSQL_ASSOC) {
return DB::_execute('fetch_array', $resourceid, $type);
}
/**
* 依据SQL语句,返回第一条查询结果
*
* @param string $query 查询语句
* @return array
*/
function fetch_first($sql) {
DB::checkquery($sql);
return DB::_execute('fetch_first', $sql);
}
/**
* 依据查询结果,返回结果数值
*
* @param resourceid $resourceid
* @return string or int
*/
function result($resourceid, $row = 0) {
return DB::_execute('result', $resourceid, $row);
}
/**
* 依据查询语句,返回结果数值
*
* @param string $query SQL查询语句
* @return unknown
*/
function result_first($sql) {
DB::checkquery($sql);
return DB::_execute('result_first', $sql);
}
/**
* 执行查询
*
* @param string $sql
* @param 类型定义 $type UNBUFFERED OR SILENT
* @return Resource OR Result
*/
function query($sql, $type = '') {
DB::checkquery($sql);
return DB::_execute('query', $sql, $type);
}
/**
* 返回select的结果行数
*
* @param resource $resourceid
* @return int
*/
function num_rows($resourceid) {
return DB::_execute('num_rows', $resourceid);
}
/**
* 返回sql语句所影响的记录行数
*
* @return int
*/
function affected_rows() {
return DB::_execute('affected_rows');
}
function free_result($query) {
return DB::_execute('free_result', $query);
}
function error() {
return DB::_execute('error');
}
function errno() {
return DB::_execute('errno');
}
function _execute($cmd , $arg1 = '', $arg2 = '') {
static $db;
if(empty($db)) $db = & DB::object();
$res = $db->$cmd($arg1, $arg2);
return $res;
}
/**
* 返回 DB object 指针
*
* @return pointer of db object from discuz core
*/
function &object($dbclass = 'db_mysql') {
static $db;
if(empty($db)) $db = new $dbclass();
return $db;
}
function checkquery($sql) {
static $status = null, $checkcmd = array('SELECT', 'UPDATE', 'INSERT', 'REPLACE', 'DELETE');
if($status === null) $status = getglobal('config/security/querysafe/status');
if($status) {
$cmd = trim(strtoupper(substr($sql, 0, strpos($sql, ' '))));
if(in_array($cmd, $checkcmd)) {
$test = DB::_do_query_safe($sql);
if($test < 1) DB::_execute('halt', 'security_error', $sql);
}
}
return true;
}
function _do_query_safe($sql) {
static $_CONFIG = null;
if($_CONFIG === null) {
$_CONFIG = getglobal('config/security/querysafe');
}
$sql = str_replace(array('\\\\', '\\\'', '\\"', '\'\''), '', $sql);
$mark = $clean = '';
if(strpos($sql, '/') === false && strpos($sql, '#') === false && strpos($sql, '-- ') === false) {
$clean = preg_replace("/'(.+?)'/s", '', $sql);
} else {
$len = strlen($sql);
$mark = $clean = '';
for ($i = 0; $i <$len; $i++) {
$str = $sql[$i];
switch ($str) {
case '\'':
if(!$mark) {
$mark = '\'';
$clean .= $str;
} elseif ($mark == '\'') {
$mark = '';
}
break;
case '/':
if(empty($mark) && $sql[$i+1] == '*') {
$mark = '/*';
$clean .= $mark;
$i++;
} elseif($mark == '/*' && $sql[$i -1] == '*') {
$mark = '';
$clean .= '*';
}
break;
case '#':
if(empty($mark)) {
$mark = $str;
$clean .= $str;
}
break;
case "\n":
if($mark == '#' || $mark == '--') {
$mark = '';
}
break;
case '-':
if(empty($mark)&& substr($sql, $i, 3) == '-- ') {
$mark = '-- ';
$clean .= $mark;
}
break;
default:
break;
}
$clean .= $mark ? '' : $str;
}
}
$clean = preg_replace("/[^a-z0-9_\-\(\)#\*\/\"]+/is", "", strtolower($clean));
if($_CONFIG['afullnote']) {
$clean = str_replace('/**/','',$clean);
}
if(is_array($_CONFIG['dfunction'])) {
foreach($_CONFIG['dfunction'] as $fun) {
if(strpos($clean, $fun.'(') !== false) return '-1';
}
}
if(is_array($_CONFIG['daction'])) {
foreach($_CONFIG['daction'] as $action) {
if(strpos($clean,$action) !== false) return '-3';
}
}
if($_CONFIG['dlikehex'] && strpos($clean, 'like0x')) {
return '-2';
}
if(is_array($_CONFIG['dnote'])) {
foreach($_CONFIG['dnote'] as $note) {
if(strpos($clean,$note) !== false) return '-4';
}
}
return 1;
}
}
//session类
class discuz_session {
var $sid = null;
var $var;
var $isnew = false;
//初始化session数组
var $newguest = array('sid' => 0, 'ip1' => 0, 'ip2' => 0, 'ip3' => 0, 'ip4' => 0,
'uid' => 0, 'username' => '', 'groupid' => 7, 'invisible' => 0, 'action' => 0,
'lastactivity' => 0, 'fid' => 0, 'tid' => 0, 'lastolupdate' => 0);
var $old = array('sid' => '', 'ip' => '', 'uid' => 0);
function discuz_session($sid = '', $ip = '', $uid = 0) {
$this->old = array('sid' => $sid, 'ip' => $ip, 'uid' => $uid);
$this->var = $this->newguest;
if(!empty($ip)) {
$this->init($sid, $ip, $uid);
}
}
//设置
function set($key, $value) {
if(isset($this->newguest[$key])) {
$this->var[$key] = $value;
} elseif ($key == 'ip') {
$ips = explode('.', $value);
$this->set('ip1', $ips[0]);
$this->set('ip2', $ips[1]);
$this->set('ip3', $ips[2]);
$this->set('ip4', $ips[3]);
}
}
//获取
function get($key) {
if(isset($this->newguest[$key])) {
return $this->var[$key];
} elseif ($key == 'ip') {
return $this->get('ip1').'.'.$this->get('ip2').'.'.$this->get('ip3').'.'.$this->get('ip4');
}
}
//初始化
function init($sid, $ip, $uid) {
$this->old = array('sid' => $sid, 'ip' => $ip, 'uid' => $uid);
$session = array();
if($sid) {
$session = DB::fetch_first("SELECT * FROM ".DB::table('common_session').
" WHERE sid='$sid' AND CONCAT_WS('.', ip1,ip2,ip3,ip4)='$ip'");
}
if(empty($session) || $session['uid'] != $uid) {
$session = $this->create($ip, $uid);
}
$this->var = $session;
$this->sid = $session['sid'];
}
//创建
function create($ip, $uid) {
$this->isnew = true;
$this->var = $this->newguest;
$this->set('sid', random(6));
$this->set('uid', $uid);
$this->set('ip', $ip);
$uid && $this->set('invisible', getuserprofile('invisible'));
$this->set('lastactivity', time());
$this->sid = $this->var['sid'];
return $this->var;
}
//删除
function delete() {
global $_G;
$onlinehold = $_G['setting']['onlinehold'];
$guestspan = 60;
$onlinehold = time() - $onlinehold;
$guestspan = time() - $guestspan;
$condition = " sid='{$this->sid}' ";
$condition .= " OR lastactivity<$onlinehold ";
$condition .= " OR (uid='0' AND ip1='{$this->var['ip1']}' AND ip2='{$this->var['ip2']}' AND ip3='{$this->var['ip3']}' AND ip4='{$this->var['ip4']}' AND lastactivity>$guestspan) ";
$condition .= $this->var['uid'] ? " OR (uid='{$this->var['uid']}') " : '';
DB::delete('common_session', $condition);
}
//更新数据
function update() {
global $_G;
if($this->sid !== null) {
$data = daddslashes($this->var);
if($this->isnew) {
$this->delete();
DB::insert('common_session', $data, false, false, true);
} else {
DB::update('common_session', $data, "sid='$data[sid]'");
}
$_G['session'] = $data;
dsetcookie('sid', $this->sid, 86400);
}
}
/**
* 取在线用户数量
*
* @param int $type 0=全部 1=会员 2=游客
* @return int
*/
function onlinecount($type = 0) {
$condition = $type == 1 ? ' WHERE uid>0 ' : ($type == 2 ? ' WHERE invisible=1 ' : '');
return DB::result_first("SELECT count(*) FROM ".DB::table('common_session').$condition);
}
}
class discuz_process
{
function islocked($process, $ttl = 0) {
$ttl = $ttl < 1 ? 600 : intval($ttl);
if(discuz_process::_status('get', $process)) {
return true;
} else {
return discuz_process::_find($process, $ttl);
}
}
function unlock($process) {
discuz_process::_status('rm', $process);
discuz_process::_cmd('rm', $process);
}
function _status($action, $process) {
static $plist = array();
switch ($action) {
case 'set' : $plist[$process] = true; break;
case 'get' : return !empty($plist[$process]); break;
case 'rm' : $plist[$process] = null; break;
case 'clear' : $plist = array(); break;
}
return true;
}
function _find($name, $ttl) {
if(!discuz_process::_cmd('get', $name)) {
discuz_process::_cmd('set', $name, $ttl);
$ret = false;
} else {
$ret = true;
}
discuz_process::_status('set', $name);
return $ret;
}
function _cmd($cmd, $name, $ttl = 0) {
static $allowmem;
if($allowmem === null) {
$allowmem = memory('check') == 'memcache';
}
if($allowmem) {
return discuz_process::_process_cmd_memory($cmd, $name, $ttl);
} else {
return discuz_process::_process_cmd_db($cmd, $name, $ttl);
}
}
function _process_cmd_memory($cmd, $name, $ttl = 0) {
return memory($cmd, 'process_lock_'.$name, time(), $ttl);
}
function _process_cmd_db($cmd, $name, $ttl = 0) {
$ret = '';
switch ($cmd) {
case 'set':
$ret = DB::insert('common_process', array('processid' => $name, 'expiry' => time() + $ttl), false, true);
break;
case 'get':
$ret = DB::fetch_first("SELECT * FROM ".DB::table('common_process')." WHERE processid='$name'");
if(empty($ret) || $ret['expiry'] < time()) {
$ret = false;
} else {
$ret = true;
}
break;
case 'rm':
$ret = DB::delete('common_process', "processid='$name' OR expiry<".time());
break;
}
return $ret;
}
}
/**
* Discuz 内存读写引擎
* 支持 memcache, eAccelerator, XCache
*
* 使用的时候建议直接利用函数 memory()
*/
class discuz_memory
{
var $config;
var $extension = array();
var $memory;
var $prefix;
var $type;
var $keys;
var $enable = false;
/**
* 确认当前系统支持的内存读写接口
* @return discuz_memory
*/
function discuz_memory() {
$this->extension['eaccelerator'] = function_exists('eaccelerator_get');
$this->extension['apc'] = function_exists('apc_fetch');
$this->extension['xcache'] = function_exists('xcache_get');
$this->extension['memcache'] = extension_loaded('memcache');
}
/**
* 依据config当中设置,初始化内存引擎
* @param unknown_type $config
*/
function init($config) {
$this->config = $config;
$this->prefix = empty($config['prefix']) ? substr(md5($_SERVER['HTTP_HOST']), 0, 6).'_' : $config['prefix'];
$this->keys = array();
if($this->extension['memcache'] && !empty($config['memcache']['server'])) {
require_once libfile('class/memcache');
$this->memory = new discuz_memcache();
$this->memory->init($this->config['memcache']);
if(!$this->memory->enable) {
$this->memory = null;
}
}
if(!is_object($this->memory) && $this->extension['eaccelerator'] && $this->config['eaccelerator']) {
require_once libfile('class/eaccelerator');
$this->memory = new discuz_eaccelerator();
$this->memory->init(null);
}
if(!is_object($this->memory) && $this->extension['xcache'] && $this->config['xcache']) {
require_once libfile('class/xcache');
$this->memory = new discuz_xcache();
$this->memory->init(null);
}
if(!is_object($this->memory) && $this->extension['apc'] && $this->config['apc']) {
require_once libfile('class/apc');
$this->memory = new discuz_apc();
$this->memory->init(null);
}
if(is_object($this->memory)) {
$this->enable = true;
$this->type = str_replace('discuz_', '', get_class($this->memory));
$this->keys = $this->get('memory_system_keys');
$this->keys = !is_array($this->keys) ? array() : $this->keys;
}
}
/**
* 读取内存
*
* @param string $key
* @return mix
*/
function get($key) {
$ret = null;
if($this->enable) {
$ret = $this->memory->get($this->_key($key));
if(!is_array($ret)) {
$ret = null;
if(array_key_exists($key, $this->keys)) {
unset($this->keys[$key]);
$this->memory->set($this->_key('memory_system_keys'), array($this->keys));
}
} else {
return $ret[0];
}
}
return $ret;
}
/**
* 写入内存
*
* @param string $key
* @param array_string_number $value
* @param int过期时间 $ttl
* @return boolean
*/
function set($key, $value, $ttl = 0) {
$ret = null;
if($this->enable) {
$ret = $this->memory->set($this->_key($key), array($value), $ttl);
if($ret) {
$this->keys[$key] = true;
$this->memory->set($this->_key('memory_system_keys'), array($this->keys));
}
}
return $ret;
}
/**
* 删除一个内存单元
* @param 键值string $key
* @return boolean
*/
function rm($key) {
$ret = null;
if($this->enable) {
$ret = $this->memory->rm($this->_key($key));
unset($this->keys[$key]);
$this->memory->set($this->_key('memory_system_keys'), array($this->keys));
}
return $ret;
}
/**
* 清除当前使用的所有内存
*/
function clear() {
if($this->enable && is_array($this->keys)) {
if(method_exists($this->memory, 'clear')) {
$this->memory->clear();
} else {
$this->keys['memory_system_keys'] = true;
foreach ($this->keys as $k => $v) {
$this->memory->rm($this->_key($k));
}
}
}
$this->keys = array();
return true;
}
/**
* 内部函数 追加键值前缀
* @param string $str
* @return boolean
*/
function _key($str) {
return ($this->prefix).$str;
}
}
?>