Discuz X3核心文件解析
<?php
/**
* [Discuz!] (C)2001-2099 Comsenz Inc.
* This is NOT a freeware, use is subject to license terms
*
* $Id: discuz_application.php 34170 2013-10-28 02:58:29Z nemohou $
*/
if(!defined('IN_DISCUZ')) {
exit('Access Denied');
}
class discuz_application extends discuz_base{
var $mem = null;
var $session = null;
var $config = array();
var $var = array();
var $cachelist = array();
var $init_db = true;
var $init_setting = true;
var $init_user = true;
var $init_session = true;
var $init_cron = true;
var $init_misc = true;
var $init_mobile = true;
var $initated = false;//初始化工作未完成标志
var $superglobal = array(//超全局变量
'GLOBALS' => 1,
'_GET' => 1,
'_POST' => 1,
'_REQUEST' => 1,
'_COOKIE' => 1,
'_SERVER' => 1,
'_ENV' => 1,
'_FILES' => 1,
);
static function &instance() {//实例化
static $object;
if(empty($object)) {
$object = new self();
}
return $object;
}
public function __construct() {
$this->_init_env();//初始化环境变量
$this->_init_config();//初始化配置变量
$this->_init_input();//初始化输入
$this->_init_output(); //初始化输出
}
public function init() {
if(!$this->initated) {
$this->_init_db();//初始化数据库
$this->_init_setting(); //系统设置初始化
$this->_init_user();//用户信息初始化
$this->_init_session();//session操作初始化
$this->_init_mobile(); //手机功能初始化
$this->_init_cron(); //计划任务初始化
$this->_init_misc();//其他功能初始化
}
$this->initated = true;//设置完成标志
}
//环境变量初始化方法
private function _init_env() {
error_reporting(E_ERROR);//定义错误报告等级
if(PHP_VERSION < '5.3.0') {
set_magic_quotes_runtime(0);//设置set_magic_quotes_runtime
}
define('MAGIC_QUOTES_GPC', function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()); //定义MAGIC_QUOTES_GPC
define('ICONV_ENABLE', function_exists('iconv'));//定义转码函数常量,如果 iconv函数支持,则为TRUE
define('MB_ENABLE', function_exists('mb_convert_encoding'));//转码函数是否支持
define('EXT_OBGZIP', function_exists('ob_gzhandler'));//缓存输出句柄函数
define('TIMESTAMP', time());//定义当前时间戳常量
$this->timezone_set();
/*如果系统核心函数库文件未include,则include,
* 如果核心函数库文件缺失,则退出,
*因为function_core.php是系统本身的函数库,必须加载
*/
if(!defined('DISCUZ_CORE_FUNCTION') && !@include(DISCUZ_ROOT.'./source/function/function_core.php')) {
exit('function_core.php is missing');
}
/*
* 以下6行代码的作用是设置内存使用限制,
* 如果小于32M,则增加为128M,
* 因为memory_limit小于32M,可能会不够用,
* 毕竟X系统比较大,可能内存会使用的多点,
* 如果不支持ini_set函数,就得去php.ini中修改了。
*/
if(function_exists('ini_get')) {
$memorylimit = @ini_get('memory_limit');
if($memorylimit && return_bytes($memorylimit) < 33554432 && function_exists('ini_set')) {
ini_set('memory_limit', '128m');
}
}
define('IS_ROBOT', checkrobot());//检测机器人
foreach ($GLOBALS as $key => $value) {//注销所有的超级变量。
if (!isset($this->superglobal[$key])) {
$GLOBALS[$key] = null; unset($GLOBALS[$key]);
}
}
global $_G;//$_G大数组是Discuz中自定义的超级变量
$_G = array(
'uid' => 0,//uid
'username' => '',//用户名
'adminid' => 0,//adminid标识
'groupid' => 1, //用户组ID
'sid' => '', // sessionID
'formhash' => '',//表单验证认证
'connectguest' => 0,
'timestamp' => TIMESTAMP,//时间戳
'starttime' => microtime(true),//开始时间
'clientip' => $this->_get_client_ip(), //客户端IP
'remoteport' => $_SERVER['REMOTE_PORT'],//远程端口号
'referer' => '',//referer地址
'charset' => '', //字符串编码
'gzipcompress' => '',//gzip
'authkey' => '', //authkey 认证码
'timenow' => array(),//当前时间
'widthauto' => 0,
'disabledwidthauto' => 0,
'PHP_SELF' => '',//PHP_SELF
'siteurl' => '',//网站地址
'siteroot' => '', //网站根目录
'siteport' => '',//网站端口号
'pluginrunlist' => !defined('PLUGINRUNLIST') ? array() : explode(',', PLUGINRUNLIST),
'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,
'tid' => 0,
'forum' => array(),//论坛板块数组
'thread' => array(),//论坛相关帖子数组
'rssauth' => '',//RSS订阅认证
'home' => array(), //home功能相关数组
'space' => array(),//space功能相关数组
'block' => array(),//块信息数组
'article' => array(),
'action' => array(
'action' => APPTYPEID,
'fid' => 0,
'tid' => 0,
),
'mobile' => '',//手机信息
'notice_structure' => array(
'mypost' => array('post','pcomment','activity','reward','goods','at'),
'interactive' => array('poke','friend','wall','comment','click','sharenotice'),
'system' => array('system','myapp','credit','group','verify','magic','task','show','group','pusearticle','mod_member','blog','article'),
'manage' => array('mod_member','report','pmreport'),
'app' => array(),
),
'mobiletpl' => array('1' => 'mobile', '2' => 'touch', '3' => 'wml','yes' => 'mobile'),
);
$_G['PHP_SELF'] = dhtmlspecialchars($this->_get_script_url());//网站地址
$_G['basescript'] = CURSCRIPT;//当前脚本
$_G['basefilename'] = basename($_G['PHP_SELF']);//当前脚本名称
$sitepath = substr($_G['PHP_SELF'], 0, strrpos($_G['PHP_SELF'], '/'));//网站根地址
if(defined('IN_API')) {
$sitepath = preg_replace("/\/api\/?.*?$/i", '', $sitepath);
} elseif(defined('IN_ARCHIVER')) {
$sitepath = preg_replace("/\/archiver/i", '', $sitepath);
}
$_G['isHTTPS'] = ($_SERVER['HTTPS'] && strtolower($_SERVER['HTTPS']) != 'off') ? true : false;
$_G['siteurl'] = dhtmlspecialchars('http'.($_G['isHTTPS'] ? 's' : '').'://'.$_SERVER['HTTP_HOST'].$sitepath.'/');
$url = parse_url($_G['siteurl']);
$_G['siteroot'] = isset($url['path']) ? $url['path'] : '';
$_G['siteport'] = empty($_SERVER['SERVER_PORT']) || $_SERVER['SERVER_PORT'] == '80' || $_SERVER['SERVER_PORT'] == '443' ? '' : ':'.$_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;
}
private function _get_script_url() {
if(!isset($this->var['PHP_SELF'])){
$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']));
$this->var['PHP_SELF'][0] != '/' && $this->var['PHP_SELF'] = '/'.$this->var['PHP_SELF'];
} else {
system_error('request_tainting');
}
}
return $this->var['PHP_SELF'];
}
private function _init_input() { //输入初始化方法
/*
* 以下代码未GPC安全机制,进行转义
*/
if (isset($_GET['GLOBALS']) ||isset($_POST['GLOBALS']) || isset($_COOKIE['GLOBALS']) || isset($_FILES['GLOBALS'])) {
system_error('request_tainting');
}
/*
* 以下代码意思是,如果cookie的键值等于定义的键值,那么截取cookiepre
*/
if(MAGIC_QUOTES_GPC) {
$_GET = dstripslashes($_GET);
$_POST = dstripslashes($_POST);
$_COOKIE = dstripslashes($_COOKIE);
}
$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;
}
}
//合并$_POST和$_GET
if($_SERVER['REQUEST_METHOD'] == 'POST' && !empty($_POST)) {
$_GET = array_merge($_GET, $_POST);
}
if(isset($_GET['page'])) {
$_GET['page'] = rawurlencode($_GET['page']);
}
if(!(!empty($_GET['handlekey']) && preg_match('/^\w+$/', $_GET['handlekey']))) {
unset($_GET['handlekey']);
}
//然后把$_POST和$_GET的值都赋予gp变量中,方便使用
if(!empty($this->var['config']['input']['compatible'])) {
foreach($_GET as $k => $v) {
$this->var['gp_'.$k] = daddslashes($v);
}
}
//获得$mod变量 ?mod=xxx,则$this->var['mod']为xxx
$this->var['mod'] = empty($_GET['mod']) ? '' : dhtmlspecialchars($_GET['mod']);
//是否需要ajax方式
$this->var['inajax'] = empty($_GET['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($_GET['page']) ? 1 : max(1, intval($_GET['page']));
//sid获取
$this->var['sid'] = $this->var['cookie']['sid'] = isset($this->var['cookie']['sid']) ? dhtmlspecialchars($this->var['cookie']['sid']) : '';
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']);
}
private function _init_config() {//获得配置文件
$_config = array();
//加载全局配置文件
@include DISCUZ_ROOT.'./config/config_global.php';
//以下代码为:如果config不存在,要么没安装,要么文件不存在,系统报错
if(empty($_config)) {
if(!file_exists(DISCUZ_ROOT.'./data/install.lock')) {
header('location: install');
exit;
} else {
system_error('config_notfound');
}
}
//设置安全验证的authkey
if(empty($_config['security']['authkey'])) {
$_config['security']['authkey'] = md5($_config['cookie']['cookiepre'].$_config['db'][1]['dbname']);
}
//以下代码为是否调试模式,
if(empty($_config['debug']) || !file_exists(libfile('function/debug'))) {
define('DISCUZ_DEBUG', false);
error_reporting(0);
} elseif($_config['debug'] === 1 || $_config['debug'] === 2 || !empty($_REQUEST['debug']) && $_REQUEST['debug'] === $_config['debug']) {
define('DISCUZ_DEBUG', true);
error_reporting(E_ERROR);
if($_config['debug'] === 2) {
error_reporting(E_ALL);
}
} else {
define('DISCUZ_DEBUG', false);
error_reporting(0);
}
//定义静态文件常量,如:css,img等,如果$_config['output']['staticurl']为空,
//则是默认的static目录,就是默认目录
define('STATICURL', !empty($_config['output']['staticurl']) ? $_config['output']['staticurl'] : 'static/');
$this->var['staticurl'] = STATICURL;
//引用$_config变量,改变$this->config,则$_config改变,保持统一
$this->config = & $_config;
$this->var['config'] = & $_config;
//设置cookie域,一般是设置目录域。/不存在则加上/,安全性更高
if(substr($_config['cookie']['cookiepath'], 0, 1) != '/') {
$this->var['config']['cookie']['cookiepath'] = '/'.$this->var['config']['cookie']['cookiepath'];
}
$this->var['config']['cookie']['cookiepre'] = $this->var['config']['cookie']['cookiepre'].substr(md5($this->var['config']['cookie']['cookiepath'].'|'.$this->var['config']['cookie']['cookiedomain']), 0, 4).'_';
}
private function _init_output() {//输出初始化方法
//验证码设置,加载include/misc/misc_security.php文件,验证功能;
if($this->config['security']['attackevasive'] && (!defined('CURSCRIPT') || !in_array($this->var['mod'], array('seccode', 'secqaa', 'swfupload')) && !defined('DISABLEDEFENSE'))) {
require_once libfile('misc/security', 'include');
}
//是否开启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);
//定义输出缓存
if(!ob_start($allowgzip ? 'ob_gzhandler' : null)) {
ob_start();
}
//把配置文件中的字符集赋予全局变量中
setglobal('charset', $this->config['output']['charset']);
define('CHARSET', $this->config['output']['charset']);
if($this->config['output']['forceheader']) {
//设置网页编码,强制输出
@header('Content-Type: text/html; charset='.CHARSET);
}
}
public function reject_robot() { //拒绝机器人访问,设置为403错误
if(IS_ROBOT) {
exit(header("HTTP/1.1 403 Forbidden"));
}
}
private function _xss_check() { //检测xss漏洞,UBB
static $check = array('"', '>', '<', '\'', '(', ')', 'CONTENT-TRANSFER-ENCODING');
if(isset($_GET['formhash']) && $_GET['formhash'] !== formhash()) {
system_error('request_tainting');
}
if($_SERVER['REQUEST_METHOD'] == 'GET' ) {
$temp = $_SERVER['REQUEST_URI'];
} elseif(empty ($_GET['formhash'])) {
$temp = $_SERVER['REQUEST_URI'].file_get_contents('php://input');
} else {
$temp = '';
}
if(!empty($temp)) {
$temp = strtoupper(urldecode(urldecode($temp)));
foreach ($check as $str) {
if(strpos($temp, $str) !== false) {
system_error('request_tainting');
}
}
}
return true;
}
private function _get_client_ip() { //得到客户端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;
}
private function _init_db() {//初始化数据库
if($this->init_db) {
$driver = function_exists('mysql_connect') ? 'db_driver_mysql' : 'db_driver_mysqli';
if(getglobal('config/db/slave')) {//是否存在从数据连接,存在则初始化
$driver = function_exists('mysql_connect') ? 'db_driver_mysql_slave' : 'db_driver_mysqli_slave';
}
DB::init($driver, $this->config['db']);
}
}
private function _init_session() { //session初始化方法
$sessionclose = !empty($this->var['setting']['sessionclose']);
$this->session = $sessionclose ? new discuz_session_close() : 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
//如果sid不为cookie中的sid,则重写sid到cookie
if(!empty($this->var['sid']) && $this->var['sid'] != $this->var['cookie']['sid']) {
dsetcookie('sid', $this->var['sid'], 86400);
}
if($this->session->isnew) {
//如果发现IP在禁止范围里,则设置该客户端用户组为6,则:禁止IP用户组
if(ipbanned($this->var['clientip'])) {
$this->session->set('groupid', 6);
}
}
if($this->session->get('groupid') == 6) {
$this->var['member']['groupid'] = 6;
if(!defined('IN_MOBILE_API')) {
sysmessage('user_banned');//提示IP禁止
} else {
mobile_core::result(array('error' => 'user_banned'));
}
}
//最近活动检测,600秒,如果用户在600秒里不活动,则设置最后访问时间点
if($this->var['uid'] && !$sessionclose && ($this->session->isnew || ($this->session->get('lastactivity') + 600) < TIMESTAMP)) {
$this->session->set('lastactivity', TIMESTAMP);
if($this->session->isnew) {
if($this->var['member']['lastip'] && $this->var['member']['lastvisit']) {
dsetcookie('lip', $this->var['member']['lastip'].','.$this->var['member']['lastvisit']);
}
C::t('common_member_status')->update($this->var['uid'], array('lastip' => $this->var['clientip'], 'port' => $this->var['remoteport'], 'lastvisit' => TIMESTAMP));
}
}
}
}
private function _init_user() {//用户初始化方法
if($this->init_user) {
//得到auth,username\tuid的加密信息
if($auth = getglobal('auth', 'cookie')) {
//进行解密
$auth = daddslashes(explode("\t", authcode($auth, 'DECODE')));
}
//得到用户名和用户密码,如果auth为空,或者缺失uid和username中的一个,则为空
list($discuz_pw, $discuz_uid) = empty($auth) || count($auth) < 2 ? array('', '') : $auth;
//如果uid存在,则得到该用户信息
if($discuz_uid) {
$user = getuserbyuid($discuz_uid, 1);
}
//如果用户存在,且密码正确,则用户信息写进全局变量中
if(!empty($user) && $user['password'] == $discuz_pw) {
if(isset($user['_inarchive'])) {
C::t('common_member_archive')->move_to_master($discuz_uid);
}
$this->var['member'] = $user;
} else {
$user = array();//user定义为空数组
$this->_init_guest();//否则为游客,游客初始化方法
}
//用户组过期检测
if($user && $user['groupexpiry'] > 0 && $user['groupexpiry'] < TIMESTAMP) {
$memberfieldforum = C::t('common_member_field_forum')->fetch($discuz_uid);
$groupterms = dunserialize($memberfieldforum['groupterms']);
if(!empty($groupterms['main'])) {
C::t("common_member")->update($user['uid'], array('groupexpiry'=> 0, 'groupid' => $groupterms['main']['groupid'], 'adminid' => $groupterms['main']['adminid']));
$user['groupid'] = $groupterms['main']['groupid'];
$user['adminid'] = $groupterms['main']['adminid'];
unset($groupterms['main'], $groupterms['ext'][$this->var['member']['groupid']]);
$this->var['member'] = $user;
C::t('common_member_field_forum')->update($discuz_uid, array('groupterms' => serialize($groupterms)));
} elseif((getgpc('mod') != 'spacecp' || CURSCRIPT != 'home') && CURSCRIPT != 'member') {
dheader('location: home.php?mod=spacecp&ac=usergroup&do=expiry');
}
}
if($user && $user['freeze'] && (getgpc('mod') != 'spacecp' && getgpc('mod') != 'misc' || CURSCRIPT != 'home') && CURSCRIPT != 'member' && CURSCRIPT != 'misc') {
dheader('location: home.php?mod=spacecp&ac=profile&op=password');
}
//用户组数据缓存
$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(); //游客
}
setglobal('groupid', getglobal('groupid', 'member'));
!empty($this->cachelist) && loadcache($this->cachelist);
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']]);
}
if($this->var['group']['allowmakehtml'] && isset($_GET['_makehtml'])) {
$this->var['makehtml'] = 1;
$this->_init_guest();
loadcache(array('usergroup_7'));
$this->var['group'] = $this->var['cache']['usergroup_7'];
unset($this->var['inajax']);
}
if(empty($this->var['cookie']['lastvisit'])) {
$this->var['member']['lastvisit'] = TIMESTAMP - 3600;
dsetcookie('lastvisit', TIMESTAMP - 3600, 86400 * 30);//cookie中如果为记录最后访问时间,则写入
} else {
$this->var['member']['lastvisit'] = $this->var['cookie']['lastvisit'];//否则,写入全局变量
}
//以下四行是把用户的uid,用户名,管理组id,用户组写入全局变量中
setglobal('uid', getglobal('uid', 'member'));
setglobal('username', getglobal('username', 'member'));
setglobal('adminid', getglobal('adminid', 'member'));
setglobal('groupid', getglobal('groupid', 'member'));
if($this->var['member']['newprompt']) {
$this->var['member']['newprompt_num'] = C::t('common_member_newprompt')->fetch($this->var['member']['uid']);
$this->var['member']['newprompt_num'] = unserialize($this->var['member']['newprompt_num']['data']);
$this->var['member']['category_num'] = helper_notification::get_categorynum($this->var['member']['newprompt_num']);
}
}
private function _init_guest() {//游客初始化方法
$username = '';
$groupid = 7;
if(!empty($this->var['cookie']['con_auth_hash']) && ($openid = authcode($this->var['cookie']['con_auth_hash']))) {
$this->var['connectguest'] = 1;
$username = 'QQ_'.substr($openid, -6);
$this->var['setting']['cacheindexlife'] = 0;
$this->var['setting']['cachethreadlife'] = 0;
$groupid = $this->var['setting']['connect']['guest_groupid'] ? $this->var['setting']['connect']['guest_groupid'] : $this->var['setting']['newusergroupid'];
}
setglobal('member', array( 'uid' => 0, 'username' => $username, 'adminid' => 0, 'groupid' => $groupid, 'credits' => 0, 'timeoffset' => 9999));
}
private 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) {
discuz_cron::run();//运行
}
}
}
private function _init_misc() {
if($this->config['security']['urlxssdefend'] && !defined('DISABLEXSSCHECK')) {
$this->_xss_check();
}
if(!$this->init_misc) {
return false;
}
lang('core');//加载core语言包
//设置用户时区timeoffset
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) {
$allowvisitflag = in_array(CURSCRIPT, array('member')) || defined('ALLOWGUEST') && ALLOWGUEST;
if($this->var['group'] && isset($this->var['group']['allowvisit']) && !$this->var['group']['allowvisit']) {
if($this->var['uid'] && !$allowvisitflag) {
if(!defined('IN_MOBILE_API')) {
showmessage('user_banned');//检测是否为禁止访问
} else {
mobile_core::result(array('error' => 'user_banned'));
}
} elseif((!defined('ALLOWGUEST') || !ALLOWGUEST) && !in_array(CURSCRIPT, array('member', 'api')) && !$this->var['inajax']) {
if(!defined('IN_MOBILE_API')) {
dheader('location: member.php?mod=logging&action=login&referer='.rawurlencode($this->var['siteurl'].$this->var['basefilename'].($_SERVER['QUERY_STRING'] ? '?'.$_SERVER['QUERY_STRING'] : '')));
} else {
mobile_core::result(array('error' => 'to_login'));
}
}
}
//如果用户状态为-1,则提示禁止访问
if(isset($this->var['member']['status']) && $this->var['member']['status'] == -1 && !$allowvisitflag) {
if(!defined('IN_MOBILE_API')) {
showmessage('user_banned');
} else {
mobile_core::result(array('error' => 'user_banned'));
}
}
}
//ip权限检测
if($this->var['setting']['ipaccess'] && !ipaccess($this->var['clientip'], $this->var['setting']['ipaccess'])) {
if(!defined('IN_MOBILE_API')) {
showmessage('user_banned');
} else {
mobile_core::result(array('error' => 'user_banned'));
}
}
//论坛如果为关闭,只有管理员可以访问,其他则提示关闭原因
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 = C::t('common_setting')->fetch('closedreason');
$closedreason = str_replace(':', ':', $closedreason);
if(!defined('IN_MOBILE_API')) {
showmessage($closedreason ? $closedreason : 'board_closed', NULL, array('adminemail' => $this->var['setting']['adminemail']), array('login' => 1));
} else {
mobile_core::result(array('error' => $closedreason ? $closedreason : 'board_closed'));
}
}
}
//私密板块访问设置
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 cache状态设置
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(isset($this->var['member']['conisbind']) && $this->var['member']['conisbind'] && $this->var['setting'] && $this->var['setting']['connect']['newbiespan'] !== '') {
$this->var['setting']['newbiespan'] = $this->var['setting']['connect']['newbiespan'];
}
$lastact = TIMESTAMP."\t".dhtmlspecialchars(basename($this->var['PHP_SELF']))."\t".dhtmlspecialchars($this->var['mod']);
dsetcookie('lastact', $lastact, 86400);
setglobal('currenturl_encode', base64_encode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']));
if((!empty($_GET['fromuid']) || !empty($_GET['fromuser'])) && ($this->var['setting']['creditspolicy']['promotion_visit'] || $this->var['setting']['creditspolicy']['promotion_register'])) {
require_once libfile('misc/promotion', 'include');
}
//SEO keywords
$this->var['seokeywords'] = !empty($this->var['setting']['seokeywords'][CURSCRIPT]) ? $this->var['setting']['seokeywords'][CURSCRIPT] : '';
//SEO 网站描述
$this->var['seodescription'] = !empty($this->var['setting']['seodescription'][CURSCRIPT]) ? $this->var['setting']['seodescription'][CURSCRIPT] : '';
}
private 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();
}
}
public function _init_style() { //模板初始化方法
if(defined('IN_MOBILE')) {
$mobile = max(1, intval(IN_MOBILE));
if($mobile && $this->var['setting']['styleid'.$mobile]) {
$styleid = $this->var['setting']['styleid'.$mobile];
}
} else {
$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']);
}
private function _init_mobile() { //手机访问设置
if(!$this->init_mobile) {
return false;
}
//允许手机访问
if(!$this->var['setting'] || !$this->var['setting']['mobile']['allowmobile'] || !is_array($this->var['setting']['mobile']) || IS_ROBOT) {
$nomobile = true;
$unallowmobile = true;
}
$mobile = getgpc('mobile');
$mobileflag = isset($this->var['mobiletpl'][$mobile]);
if($mobile === 'no') {
dsetcookie('mobile', 'no', 3600);
$nomobile = true;
} elseif($this->var['cookie']['mobile'] == 'no' && $mobileflag) {
checkmobile();//检测是否为手机访问
dsetcookie('mobile', '');
} elseif($this->var['cookie']['mobile'] == 'no') {
$nomobile = true;
} elseif(!($mobile_ = checkmobile())) {
$nomobile = true;
} elseif(!$mobile) {
$mobile = isset($mobile_) ? $mobile_ : 1;
}
if(!$this->var['mobile'] && !$unallowmobile) {
if($mobileflag) {
dheader("Location:misc.php?mod=mobile");
}
}
if($nomobile || (!$this->var['setting']['mobile']['mobileforward'] && !$mobileflag)) {
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']);
return false;
} else {
return false;
}
}
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");
}
if($mobile === '3' && empty($this->var['setting']['mobile']['wml'])) {
return false;
}
define('IN_MOBILE', isset($this->var['mobiletpl'][$mobile]) ? $mobile : '2');
setglobal('gzipcompress', 0);
$arr = array();
foreach(array_keys($this->var['mobiletpl']) as $mobiletype) {
$arr[] = '&mobile='.$mobiletype;
$arr[] = 'mobile='.$mobiletype;
}
$arr = array_merge(array(strstr($_SERVER['QUERY_STRING'], '&simpletype'), strstr($_SERVER['QUERY_STRING'], 'simpletype')), $arr);
$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)) {
$_GET[$pk] = $_POST[$pk] = $this->mobile_iconv_recurrence($pv);
if(!empty($this->var['config']['input']['compatible'])) {
$this->var['gp_'.$pk] = daddslashes($_GET[$pk]);
}
}
}
}
}
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 ;
$this->var['setting']['thumbquality'] = 50;
$this->var['setting']['avatarmethod'] = 0;
$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=1&simpletype=no';
$this->var['setting']['mobile']['simpletypeurl'][1] = $this->var['siteurl'].$this->var['basefilename'].($query_sting_tmp ? '?'.$query_sting_tmp.'&' : '?').'mobile=1&simpletype=yes';
$this->var['setting']['mobile']['simpletypeurl'][2] = $this->var['siteurl'].$this->var['basefilename'].($query_sting_tmp ? '?'.$query_sting_tmp.'&' : '?').'mobile=2';
unset($query_sting_tmp);
ob_start();
}
public function timezone_set($timeoffset = 0) {//时区设置
if(function_exists('date_default_timezone_set')) {
@date_default_timezone_set('Etc/GMT'.($timeoffset > 0 ? '-' : '+').(abs($timeoffset)));
}
}
public function mobile_iconv_recurrence($value) {//手机访问再次转码
if(is_array($value)) {
foreach($value AS $key => $val) {
$value[$key] = $this->mobile_iconv_recurrence($val);
}
} else {
$value = diconv($value, 'utf-8', CHARSET);
}
return $value;
}
}
?>
Discuz X3核心文件解析的更多相关文章
- discuz 3.x 核心文件class_core.php解析
class_core.php是discuz 3.x的核心文件,几乎所有PHP脚本都有引用此文件初始化论坛运行环境.以下解析引用3.2版discuz. line 12-15:常量定义IN_DISCUZ: ...
- discuz学习,文件列表
文件颜色说明: 红色:程序核心文件,修改这类文件时千万要注意安全! 橙色:做插件几乎不会用到的文件,大概了解功能就可以了,其实我也不推荐修改这些文件 绿色:函数类文件,许多功能强大的自定义函数可以调用 ...
- springmvc笔记(基本配置,核心文件,路径,参数,文件上传,json整合)
首先导入jar包 大家注意一下我的springmvc,jackson,common-up的jar包版本.其他版本有可能出现不兼容. src文件: webroot目录: web.xml <?xml ...
- Discuz X3.2 SEO设置 title 不支持空格的解决方法
很多使用 Discuz X3.2 的同学都发现这么一个问题:在后台SEO设置-title设定的时候,即使你在连字符两侧输入了空格,在前台也显示不出来,很多同学纠结这个问题,今天终于找到了解决方法,在此 ...
- phpcms v9和discuz X3.1实现同步登陆退出论坛(已实现)
网络上文章很多,按步骤配置好了之后phpcms可以同步登录dz,但是dz登录后状态却无法同步到phpcms,网络上找了很多资料都大同小异,头大.只能自己调试了,废话不多说了. 以下网络上抄 ...
- phpcms 2008和discuz X3.1实现同步登陆退出论坛(已实现)
网络上文章很多,按步骤配置好了之后phpcms可以同步登录dz,但是dz登录后状态却无法同步到phpcms,网络上找了很多资料都大同小异,头大.只能自己调试了,废话不多说了. 以下网络上抄 ...
- 去掉删除discuz x3.2 的-Powered by Discuz!
如图discuz论坛 网站标题栏的尾巴powered by discuz!是不是很想删除呢,特别是为什么会剩下短线呢?下面就叫你如何准确删除或者修改. 工具/原料 8UFTP(使用自己熟悉的网站文件上 ...
- Python实现XML文件解析
1. XML简介 XML(eXtensible Markup Language)指可扩展标记语言,被设计用来传输和存储数据,已经日趋成为当前许多新生技术的核心,在不同的领域都有着不同的应用.它是web ...
- 如何将各种低版本的discuz版本升级到discuz x3.0
最近在做discuz改版的项目,遇到了很多问题,相信很多拥有discuz论坛的版主,站长和程序猿在升级或改版discuz的过程中遇到过和我一样的问题,所以我开了一个discuz专栏,为大家讲解一下di ...
随机推荐
- DOM解析XML文件
1.首先把第三方代码拖进工程 GDataXMLNode.h和GDataXMLNode.m这两个文件放进工程里面 2.引入libxml2库文件 3.将GDataXMLNode.h文件中的这两个东西在工程 ...
- Struts2(十四)拦截器实现权限管理
一.认识拦截器 拦截器也是一个类 拦截器可以在Action被调用之前和之后执行代码 框架很多核心功能是拦截器实现的 拦截器的特点: 拦截器自由组合,增强了灵活性.扩展性.有利于系统解耦 拦截器可以拦截 ...
- UIWebView用法详解及代码分享
今天我们来详细UIWebView用法.UIWebView是iOS内置的浏览器控件,可以浏览网页.打开文档等 能够加载html/htm.pdf.docx.txt等格式的文件. 用UIWebView我们就 ...
- Visual Studio发布Web项目报错:Unable to add 'xxx' to the Web site. Unable to add file 'xxx'. The specified file could not be encrypted.
背景 Visual Studio下的Web项目 现象 发布时遇到Unable to add 'xxx' to the Web site. Unable to add file 'xxx'. The ...
- 观察者模式--java jdk中提供的支持
一.简介 观察者设计模式有如下四个角色 抽象主题角色:把所有对观察者对象的引用保存在一个集合中,每个抽象主题角色都可以有任意数量的观察者.抽象主题提供一个接口,可以增加和删除观察者角色.一般用一个抽象 ...
- 第1章 Java中常用字符串方法总结
1.1 charAt方法——提取指定字符 1.2 codePointAt方法——提取索引字符代码点 1.3 codePointBefore方法——获取索引前一个字符的代码点 1.4 codePoint ...
- uname
uname uname用于打印操作系统和硬件架构相关的信息,对于可能在多个系统或架构上运行的Shell脚本程序很有用, 缺省选项相当于 -s 或--system $uname [-amnrsvpio] ...
- python lambda表达式简单用法
习条件运算时,对于简单的 if else 语句,可以使用三元运算来表示,即: 1 2 3 4 5 6 7 8 # 普通条件语句 if 1 == 1: name = 'wupeiqi' else ...
- POJ 2513 Colored Sticks(欧拉回路,字典树,并查集)
题意:给定一些木棒,木棒两端都涂上颜色,求是否能将木棒首尾相接,连成一条直线,要求不同木棒相接的一边必须是相同颜色的. 无向图存在欧拉路的充要条件为: ① 图是连通的: ② 所有节 ...
- 如何用dos命令运行testng
写好的自动化程序怎么让它运行呢,总不能每次都启动eclipse吧,下面就先介绍一种用dos命令运行testNG的方法. 1.把项目打成jar吧,我用的是Fat jar工具. 2.在电脑的某个盘建一个文 ...