【discuzX2】/source/class/class_core.php文件中核心基础类库中discuz_core类分析

  1. <?php  
  2.   
  3. /** 
  4.  *      [Discuz!] (C)2001-2099 Comsenz Inc. 
  5.  *      This is NOT a freeware, use is subject to license terms 
  6.  * 
  7.  *      $Id: class_core.php 24487 2011-09-21 08:13:57Z monkey $ 
  8.  */  
  9.   
  10. define('IN_DISCUZ', true);//禁止用户直接通过路径访问  
  11. error_reporting(0);//设置错误级别  
  12.   
  13. //通用基础类  
  14. class discuz_core {  
  15.   
  16.     var $db = null;//数据库db类实例化对象  
  17.   
  18.     var $mem = null;//memcached缓存对象  
  19.   
  20.     var $session = null;//session变量  
  21.   
  22.     var $config = array();//配置信息  
  23.           
  24.         //$_G数组的映射  
  25.     var $var = array();//变量数组,将超级全局变量$_G的引用赋值给了$var变量  
  26.   
  27.         //加载缓存数组  
  28.     var $cachelist = array();//缓存列表  
  29.   
  30.         //是否初始化  
  31.     var $init_setting = true;//初始化设置  
  32.     var $init_user = true;//初始化用户信息  
  33.     var $init_session = true;//初始化session信息  
  34.     var $init_cron = true;  
  35.     var $init_misc = true;  
  36.     var $init_memory = true;//初始化内存情况  
  37.     var $init_mobile = true;  
  38.   
  39.         //是否已经初始化  
  40.     var $initated = false;//初始化工作为完成标志  
  41.   
  42.         //列举全局变量,为清理做准备  
  43.     var $superglobal = array(//自定义超级全局变量  
  44.         'GLOBALS' => 1,  
  45.         '_GET' => 1,  
  46.         '_POST' => 1,  
  47.         '_REQUEST' => 1,  
  48.         '_COOKIE' => 1,  
  49.         '_SERVER' => 1,  
  50.         '_ENV' => 1,  
  51.         '_FILES' => 1,  
  52.     );  
  53.   
  54.         //建立唯一的进程  
  55.     function &instance() {//单例模式实例化一个discuz_core核心类实例化对象  
  56.         static $object;  
  57.         if(empty($object)) {  
  58.             $object = new discuz_core();//实例化一个discuz_core对象  
  59.         }  
  60.         return $object;//返回唯一的一个discuz_core类实例化对象  
  61.     }  
  62.   
  63.         //预处理的调用  
  64.     function discuz_core() {//构造函数  
  65.         $this->_init_env();//初始化环境变量  
  66.         $this->_init_config();//初始化配置变量  
  67.         $this->_init_input();//初始化输入  
  68.         $this->_init_output();//初始化输出  
  69.     }  
  70.   
  71.         //核心的初始化  
  72.     function init() {  
  73.         if(!$this->initated) {  
  74.             $this->_init_db();//数据库操作类实例化对象的初始化  
  75.             $this->_init_memory();//初始化memcache  
  76.             $this->_init_user();//用户信息初始化  
  77.             $this->_init_session();//session操作初始化  
  78.             $this->_init_setting();//系统设置初始化  
  79.             $this->_init_mobile();//手机功能初始化  
  80.             $this->_init_cron();//计划任务初始化  
  81.             $this->_init_misc();//其他功能的初始化  
  82.         }  
  83.         $this->initated = true;//初始化完成的标志  
  84.     }  
  85.   
  86.         //定义php环境信息常量和$_G全局变量  
  87.         /* 
  88.          * 1、主要讲$_G变量的引用赋值给$var数组变量 
  89.          * 2、注意:G变量是程序的全局变量,为了让程序更加高效,减少不必要的数据获取,所以程序特将经常需要用到的变量统一到 
  90.          *    G变量下,如:用户登录信息、后台设置信息、服务器环境信息、客户端cookies、数据缓存等都存放在G变量里面,在制作 
  91.          *    模板文件的时只需将G变量打印出来即可获得需要的信息是否在G变量中 
  92.          * 3、自定义变量:自定义变量是以$开头并且首位为字母或下划线的变量, 
  93.          *    如:$data、$thread、$post、$forumlist、$threadlist 
  94.          * 4、类似$_G['gp_xxx']变量都是get和post过来的数据 
  95.          */  
  96.     function _init_env() {  
  97.                 //设置错误级别  
  98.         error_reporting(E_ERROR);  
  99.         if(PHP_VERSION < '5.3.0') {  
  100.             set_magic_quotes_runtime(0);//设置set_magic_quotes_runtime  
  101.         }  
  102.   
  103.         define('DISCUZ_ROOT', substr(dirname(__FILE__), 0, -12));//定义根目录常量:"d:/wamp/www/discuz/"  
  104.         define('MAGIC_QUOTES_GPC', function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc());//定义MAGIC_QUOTES_GPC常量  
  105.         define('ICONV_ENABLE', function_exists('iconv'));//定义是否支持转码函数常量,如:iconv("gb2312","utf-8","我爱卡");//将gb2312编码转换为utf-8编码  
  106.         define('MB_ENABLE', function_exists('mb_convert_encoding'));//定义是否支持转码函数常量,跟iconv用法差不多,有稍微差异  
  107.         define('EXT_OBGZIP', function_exists('ob_gzhandler'));//缓存输出句柄函数  
  108.   
  109.         define('TIMESTAMP', time());//定义当前时间戳常量  
  110.         $this->timezone_set();//设置时区  
  111.                   
  112.                 /* 
  113.                  * 1、加载系统核心函数库文件 
  114.                  * 2、条件:常量未定义、系统函数库未加载的情况下报"系统核心函数库文件丢失"的错误,否则加载系统核心函数库文件 
  115.                  */  
  116.         if(!defined('DISCUZ_CORE_FUNCTION') && !@include(DISCUZ_ROOT.'./source/function/function_core.php')) {  
  117.             exit('function_core.php is missing');//退出,并报"系统核心函数库文件丢失的错误"  
  118.         }  
  119.   
  120.         if(function_exists('ini_get')) {//获取php.ini配置文件中设置的配置信息  
  121.             $memorylimit = @ini_get('memory_limit');//设置内存使用限制  
  122.             if($memorylimit && return_bytes($memorylimit) < 33554432 && function_exists('ini_set')) {  
  123.                 ini_set('memory_limit', '128m');//如果小于32M,则增加到128M  
  124.             }  
  125.         }  
  126.   
  127.         define('IS_ROBOT', checkrobot());//检测机器人  
  128.   
  129.                 //$GLOBALS:超全局变量,全局作用域中始终可用的内置变量,在函数和方法中无需使用 global $xxx声明  
  130.         foreach ($GLOBALS as $key => $value) {  
  131.             if (!isset($this->superglobal[$key])) {//注销没有在$superglobal中出现的超全局变量,也就是注销所有的超级全局变量  
  132.                 $GLOBALS[$key] = null; unset($GLOBALS[$key]);//设置为null并销毁  
  133.             }  
  134.         }  
  135.   
  136.                 //超级变量大数组$_G的定义,在模板文件中要使用  
  137.         global $_G;//函数体外可以使用,注意:只能在本文件中,或者include的文件中使用,并不能再整个网站中使用  
  138.         $_G = array(  
  139.             'uid' => 0,//作者UID  
  140.             'username' => '',//用户名  
  141.             'adminid' => 0,//管理组ID  
  142.             'groupid' => 1,//用户组ID  
  143.             'sid' => '',//cookie和session相关的sid  
  144.             'formhash' => '',//表单验证认证  
  145.             'timestamp' => TIMESTAMP,//时间戳  
  146.             'starttime' => dmicrotime(),//开始时间  
  147.             'clientip' => $this->_get_client_ip(),//客户端ip  
  148.             'referer' => '',//来路  
  149.             'charset' => '',//字符编码设置  
  150.             'gzipcompress' => '',//gzip  
  151.             'authkey' => '',//密钥  
  152.             'timenow' => array(),  
  153.   
  154.             'PHP_SELF' => '',//当前php脚本文件,如:"/discuz/forum.php"  
  155.             'siteurl' => '',//站点url  
  156.             'siteroot' => '',//站点根目录  
  157.             'siteport' => '',//站点端口  
  158.   
  159.             'config' => array(),//配置变量数组  
  160.             'setting' => array(),//设置变量数组  
  161.             'member' => array(),//用户信息数组  
  162.             'group' => array(),//用户组数组  
  163.             'cookie' => array(),//cookie数组  
  164.             'style' => array(),//风格数组  
  165.             'cache' => array(),//缓存列表数组  
  166.             'session' => array(),//session变量数组  
  167.             'lang' => array(),//语言包数组  
  168.             'my_app' => array(),//我的应用数组  
  169.             'my_userapp' => array(),//用户应用数组  
  170.   
  171.             'fid' => 0,//版块id  
  172.             'tid' => 0,//帖子id  
  173.             'forum' => array(),//论坛版块数组  
  174.             'thread' => array(),//论坛相关帖子数组  
  175.             'rssauth' => '',//RSS订阅认证  
  176.   
  177.             'home' => array(),//home功能相关数组  
  178.             'space' => array(),//space功能相关数组  
  179.   
  180.             'block' => array(),//块信息数组  
  181.             'article' => array(),//文章相关  
  182.   
  183.             'action' => array(  
  184.                 'action' => APPTYPEID,  
  185.                 'fid' => 0,//版块id  
  186.                 'tid' => 0,//帖子id  
  187.             ),  
  188.   
  189.             'mobile' => '',//手机信息  
  190.   
  191.         );  
  192.         $_G['PHP_SELF'] = htmlspecialchars($this->_get_script_url());//将当前脚本地址写入$_G超级变量中;结果:"/discuz/forum.php"  
  193.         $_G['basescript'] = CURSCRIPT;//当前不带扩展名的php脚本,如:"forum"  
  194.         $_G['basefilename'] = basename($_G['PHP_SELF']);//显示带有文件扩展名的php文件名称,如:"forum.php"  
  195.         $sitepath = substr($_G['PHP_SELF'], 0, strrpos($_G['PHP_SELF'], '/'));//如:"/discuz"  
  196.         if(defined('IN_API')) {  
  197.             $sitepath = preg_replace("/\/api\/?.*?$/i", '', $sitepath);  
  198.         } elseif(defined('IN_ARCHIVER')) {  
  199.             $sitepath = preg_replace("/\/archiver/i", '', $sitepath);  
  200.         }  
  201.         $_G['siteurl'] = htmlspecialchars('http://'.$_SERVER['HTTP_HOST'].$sitepath.'/');//网站地址  
  202.   
  203.         $url = parse_url($_G['siteurl']);  
  204.         $_G['siteroot'] = isset($url['path']) ? $url['path'] : '';//网站根目录,如:"/discuz"  
  205.         $_G['siteport'] = empty($_SERVER['SERVER_PORT']) || $_SERVER['SERVER_PORT'] == '80' ? '' : ':'.$_SERVER['SERVER_PORT'];//端口  
  206.   
  207.         if(defined('SUB_DIR')) {//二级目录设置情况  
  208.             $_G['siteurl'] = str_replace(SUB_DIR, '/', $_G['siteurl']);  
  209.             $_G['siteroot'] = str_replace(SUB_DIR, '/', $_G['siteroot']);  
  210.         }  
  211.   
  212.         $this->var = & $_G;//$_G变量的引用赋值给$var,以后对$_G变量或$var变量的修改会直接影响到对方  
  213.   
  214.     }  
  215.   
  216.         /* 
  217.          * 1、返回PHP_SELF当前脚本文件 
  218.          */  
  219.     function _get_script_url() {  
  220.         if($this->var['PHP_SELF'] === null){  
  221.             $scriptName = basename($_SERVER['SCRIPT_FILENAME']);  
  222.             if(basename($_SERVER['SCRIPT_NAME']) === $scriptName) {  
  223.                 $this->var['PHP_SELF'] = $_SERVER['SCRIPT_NAME'];  
  224.             } else if(basename($_SERVER['PHP_SELF']) === $scriptName) {  
  225.                 $this->var['PHP_SELF'] = $_SERVER['PHP_SELF'];  
  226.             } else if(isset($_SERVER['ORIG_SCRIPT_NAME']) && basename($_SERVER['ORIG_SCRIPT_NAME']) === $scriptName) {  
  227.                 $this->var['PHP_SELF'] = $_SERVER['ORIG_SCRIPT_NAME'];  
  228.             } else if(($pos = strpos($_SERVER['PHP_SELF'],'/'.$scriptName)) !== false) {  
  229.                 $this->var['PHP_SELF'] = substr($_SERVER['SCRIPT_NAME'],0,$pos).'/'.$scriptName;  
  230.             } else if(isset($_SERVER['DOCUMENT_ROOT']) && strpos($_SERVER['SCRIPT_FILENAME'],$_SERVER['DOCUMENT_ROOT']) === 0) {  
  231.                 $this->var['PHP_SELF'] = str_replace('\\','/',str_replace($_SERVER['DOCUMENT_ROOT'],'',$_SERVER['SCRIPT_FILENAME']));  
  232.             } else {  
  233.                 system_error('request_tainting');  
  234.             }  
  235.         }  
  236.         return $this->var['PHP_SELF'];  
  237.     }  
  238.   
  239.         /* 
  240.          * 1、合并$_POST和$_GET,然后将$_POST和$_GET的值都赋予gp变量中,方便使用 
  241.          * 2、禁止对全局变量注入 
  242.          * 3、slashes处理 
  243.          * 4、cookie处理:去掉cookie前缀 
  244.          */  
  245.     function _init_input() {  
  246.         if (isset($_GET['GLOBALS']) ||isset($_POST['GLOBALS']) ||  isset($_COOKIE['GLOBALS']) || isset($_FILES['GLOBALS'])) {  
  247.             system_error('request_tainting');//...请求中...  
  248.         }  
  249.   
  250.         if(!MAGIC_QUOTES_GPC) {//魔术函数是否开启:仅仅对$_GET、$_POST、$_COOKIE起作用;主要用于在讲数据入库前做一些安全性的转义  
  251.             $_GET = daddslashes($_GET);//对$_GET数据进行转义  
  252.             $_POST = daddslashes($_POST);//对$_POST数据进行转义  
  253.             $_COOKIE = daddslashes($_COOKIE);//对$_COOKIE数据进行转义  
  254.             $_FILES = daddslashes($_FILES);//对$_FILES数据进行转义  
  255.         }  
  256.   
  257.                 /* 
  258.                  * 1、如果cookie的键值等于定义的键值,那么截取cookie的前缀cookiepre 
  259.                  */  
  260.         $prelength = strlen($this->config['cookie']['cookiepre']);  
  261.         foreach($_COOKIE as $key => $val) {  
  262.             if(substr($key, 0, $prelength) == $this->config['cookie']['cookiepre']) {  
  263.                 $this->var['cookie'][substr($key, $prelength)] = $val;//cookie赋值  
  264.             }  
  265.         }  
  266.   
  267.                 /* 
  268.                  * 1、合并$_POST和$_GET,然后将$_POST和$_GET的值都赋予gp变量中,方便使用 
  269.                  */  
  270.         if($_SERVER['REQUEST_METHOD'] == 'POST' && !empty($_POST)) {  
  271.             $_GET = array_merge($_GET, $_POST);  
  272.         }  
  273.                   
  274.                 //diy  
  275.         if(isset($_GET['diy'])) {  
  276.             $_GET['diy'] = empty($_GET['diy']) ? '' : $_GET['diy'];  
  277.         }  
  278.   
  279.         foreach($_GET as $k => $v) {  
  280.             $this->var['gp_'.$k] = $v;//将$_POST和$_GET的值都赋予gp变量中,方便使用  
  281.         }  
  282.   
  283.                 //获取$mod变量,如:/?mod=xxx ,那么$this->var['mod']=xxx;  
  284.         $this->var['mod'] = empty($this->var['gp_mod']) ? '' : htmlspecialchars($this->var['gp_mod']);  
  285.         //是否需要ajax方式  
  286.                 $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));  
  287.         //页面获取,最小为1  
  288.                 $this->var['page'] = empty($this->var['gp_page']) ? 1 : max(1, intval($this->var['gp_page']));  
  289.         //cookie与session相关的sid的获取  
  290.                 $this->var['sid'] = $this->var['cookie']['sid'] = isset($this->var['cookie']['sid']) ? htmlspecialchars($this->var['cookie']['sid']) : '';  
  291.         $this->var['gp_handlekey'] = !empty($this->var['gp_handlekey']) && preg_match('/^\w+$/', $this->var['gp_handlekey']) ? $this->var['gp_handlekey'] : '';  
  292.   
  293.         if(empty($this->var['cookie']['saltkey'])) {//解密时可能会使用到  
  294.             $this->var['cookie']['saltkey'] = random(8);  
  295.             dsetcookie('saltkey', $this->var['cookie']['saltkey'], 86400 * 30, 1, 1);  
  296.         }  
  297.                 //密钥  
  298.         $this->var['authkey'] = md5($this->var['config']['security']['authkey'].$this->var['cookie']['saltkey']);  
  299.     }  
  300.   
  301.         /* 
  302.          * 1、主要讲$config引用赋值给$config=array()和 $var['config']=$config; 
  303.          * 2、加载配置文件 
  304.          */  
  305.     function _init_config() {  
  306.   
  307.         $_config = array();//定义$_config配置数组  
  308.         @include DISCUZ_ROOT.'./config/config_global.php';//加载全局配置文件,配置文件中是一个$_config数组  
  309.         if(empty($_config)) {//配置信息为空的情况,安装前为空  
  310.             if(!file_exists(DISCUZ_ROOT.'./data/install.lock')) {//没有安装的情况  
  311.                 header('location: install');//安装discuz论坛系统  
  312.                 exit;  
  313.             } else {  
  314.                 system_error('config_notfound');  
  315.             }  
  316.         }  
  317.   
  318.                 //设置安全认证的authkey  
  319.         if(empty($_config['security']['authkey'])) {  
  320.             $_config['security']['authkey'] = md5($_config['cookie']['cookiepre'].$_config['db'][1]['dbname']);//密钥的组成:cookie前缀+数据库的名称  
  321.         }  
  322.   
  323.                 //是否调试模式  
  324.         if(empty($_config['debug']) || !file_exists(libfile('function/debug'))) {  
  325.             define('DISCUZ_DEBUG', false);//调试模式关闭  
  326.         } elseif($_config['debug'] === 1 || $_config['debug'] === 2 || !empty($_REQUEST['debug']) && $_REQUEST['debug'] === $_config['debug']) {  
  327.             define('DISCUZ_DEBUG', true);//调试模式打开  
  328.             if($_config['debug'] == 2) {  
  329.                 error_reporting(E_ALL);//设置错误级别  
  330.             }  
  331.         } else {  
  332.             define('DISCUZ_DEBUG', false);  
  333.         }  
  334.   
  335.                 //定义静态文件常量:方便找到images、css、js素材文件  
  336.         define('STATICURL', !empty($_config['output']['staticurl']) ? $_config['output']['staticurl'] : 'static/');  
  337.         $this->var['staticurl'] = STATICURL;//素材文件url:主要用于存储images、css、js等素材文件  
  338.   
  339.         $this->config = & $_config;//配置信息的引用赋值给$config数组变量  
  340.         $this->var['config'] = & $_config;//同时配置信息的引用赋值给$var['config'],即:赋值给了$_G['config']  
  341.   
  342.                 //设置cookie域,一般是设置目录域,"/"不存在则加上"/"  
  343.         if(substr($_config['cookie']['cookiepath'], 0, 1) != '/') {//cookie路径  
  344.             $this->var['config']['cookie']['cookiepath'] = '/'.$this->var['config']['cookie']['cookiepath'];  
  345.         }  
  346.                 //定义cookie前缀,如:定义为xxx_,则为$cookie[xxx_uid]  
  347.         $this->var['config']['cookie']['cookiepre'] = $this->var['config']['cookie']['cookiepre'].substr(md5($this->var['config']['cookie']['cookiepath'].'|'.$this->var['config']['cookie']['cookiedomain']), 0, 4).'_';  
  348.   
  349.     }  
  350.   
  351.         /* 
  352.          * 1、输出处理 
  353.          * 2、get参数跨站检测 
  354.          * 3、防页面刷新 
  355.          * 4、gzip处理 
  356.          * 5、字符集处理 
  357.          */  
  358.     function _init_output() {  
  359.   
  360.         if($this->config['security']['urlxssdefend'] && $_SERVER['REQUEST_METHOD'] == 'GET' && !empty($_SERVER['REQUEST_URI'])) {  
  361.             $this->_xss_check();  
  362.         }  
  363.   
  364.                 /* 
  365.                  * 1、验证码的设置:加载include/misc/security.php文件,验证功能 
  366.                  */  
  367.         if($this->config['security']['attackevasive'] && (!defined('CURSCRIPT') || !in_array($this->var['mod'], array('seccode', 'secqaa', 'swfupload')))) {  
  368.             require_once libfile('misc/security', 'include');  
  369.         }  
  370.   
  371.                 /* 
  372.                  * 1、是否开启gzip,如果不支持gzip,则定义为false 
  373.                  */  
  374.         if(!empty($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') === false) {  
  375.             $this->config['output']['gzip'] = false;  
  376.         }  
  377.   
  378.                 //将$allowgzip写入全局变量中  
  379.         $allowgzip = $this->config['output']['gzip'] && empty($this->var['inajax']) && $this->var['mod'] != 'attachment' && EXT_OBGZIP;  
  380.         setglobal('gzipcompress', $allowgzip);  
  381.         ob_start($allowgzip ? 'ob_gzhandler' : null);//定义输出缓存  
  382.   
  383.                 //将配置文件中的字符集写入全局变量中  
  384.         setglobal('charset', $this->config['output']['charset']);  
  385.         define('CHARSET', $this->config['output']['charset']);  
  386.         if($this->config['output']['forceheader']) {  
  387.             @header('Content-Type: text/html; charset='.CHARSET);//设置网页编码,强制输出  
  388.         }  
  389.   
  390.     }  
  391.   
  392.         /* 
  393.          * 1、拒绝机器人访问,设置为403错误 
  394.          */  
  395.     function reject_robot() {  
  396.         if(IS_ROBOT) {  
  397.             exit(header("HTTP/1.1 403 Forbidden"));  
  398.         }  
  399.     }  
  400.   
  401.         /* 
  402.          * 1、检查xss漏洞、ubb漏洞 
  403.          * 2、get参数跨站检测 
  404.          */  
  405.     function _xss_check() {  
  406.         $temp = strtoupper(urldecode(urldecode($_SERVER['REQUEST_URI'])));  
  407.         if(strpos($temp, '<') !== false || strpos($temp, '"') !== false || strpos($temp, 'CONTENT-TRANSFER-ENCODING') !== false) {  
  408.             system_error('request_tainting');  
  409.         }  
  410.         return true;  
  411.     }  
  412.   
  413.         /* 
  414.          * 1、获取客户端的ip 
  415.          */  
  416.     function _get_client_ip() {  
  417.         $ip = $_SERVER['REMOTE_ADDR'];  
  418.         if (isset($_SERVER['HTTP_CLIENT_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CLIENT_IP'])) {  
  419.             $ip = $_SERVER['HTTP_CLIENT_IP'];  
  420.         } 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)) {  
  421.             foreach ($matches[0] AS $xip) {  
  422.                 if (!preg_match('#^(10|172\.16|192\.168)\.#', $xip)) {  
  423.                     $ip = $xip;  
  424.                     break;  
  425.                 }  
  426.             }  
  427.         }  
  428.         return $ip;  
  429.     }  
  430.   
  431.         /* 
  432.          * 1、初始化数据库类、同时选择主从数据库 
  433.          */  
  434.     function _init_db() {  
  435.         $class = 'db_mysql';  
  436.         if(count(getglobal('config/db/slave'))) {//是否存在从数据连接,存在则初始化  
  437.             require_once libfile('class/mysql_slave');  
  438.             $class = 'db_mysql_slave';  
  439.         }  
  440.         $this->db = & DB::object($class);  
  441.         $this->db->set_config($this->config['db']);  
  442.         $this->db->connect();//建立数据库连接  
  443.     }  
  444.   
  445.         /* 
  446.          * 1、初始化session信息 
  447.          */  
  448.     function _init_session() {  
  449.         $this->session = new discuz_session();  
  450.   
  451.         if($this->init_session)  {  
  452.             $this->session->init($this->var['cookie']['sid'], $this->var['clientip'], $this->var['uid']);  
  453.             $this->var['sid'] = $this->session->sid;//设置sid  
  454.             $this->var['session'] = $this->session->var;//设置session  
  455.   
  456.             if($this->var['sid'] != $this->var['cookie']['sid']) {  
  457.                 dsetcookie('sid', $this->var['sid'], 86400);//如果sid不为cookie中的sid,则重写sid到cookie  
  458.             }  
  459.   
  460.             if($this->session->isnew) {  
  461.                 if(ipbanned($this->var['clientip'])) {//如果发现ip在禁止范围内,则设置该客户端用户组为6,即:禁止ip用户组  
  462.                     $this->session->set('groupid', 6);  
  463.                 }  
  464.             }  
  465.   
  466.             if($this->session->get('groupid') == 6) {  
  467.                 $this->var['member']['groupid'] = 6;  
  468.                 sysmessage('user_banned');//提示ip禁止  
  469.             }  
  470.   
  471.                         /* 
  472.                          * 1、最近活动检测,600秒 
  473.                          */  
  474.             if($this->var['uid'] && ($this->session->isnew || ($this->session->get('lastactivity') + 600) < TIMESTAMP)) {  
  475.                 $this->session->set('lastactivity', TIMESTAMP);  
  476.                 if($this->session->isnew) {  
  477.                                         //如果用户在600秒内不活动,则设置最后访问时间点  
  478.                     DB::update('common_member_status', array('lastip' => $this->var['clientip'], 'lastvisit' => TIMESTAMP), "uid='".$this->var['uid']."'");  
  479.                 }  
  480.             }  
  481.   
  482.         }  
  483.     }  
  484.   
  485.         /* 
  486.          * 1、初始化当前用户信息 
  487.          */  
  488.     function _init_user() {  
  489.         if($this->init_user) {  
  490.             $discuz_uid = '';  
  491.             /*通过COOKIE取得用户信息 start*/  
  492.             /*TODO utf-8 2 GBK change start*/  
  493.             /*$_cookie_userName = $_COOKIE["USERNAME"];*/  
  494.             $username_tmp = $_COOKIE["USERNAME"];  
  495.             $a=urldecode($username_tmp);  
  496.             /*$a=mb_convert_encoding($a, 'GB2312', 'UTF-8'); */  
  497.             $a=diconv($a, 'UTF-8', 'GBK');  
  498.             $_cookie_userName = $a;  
  499.             /*TODO utf-8 2 GBK change start*/  
  500.             $_cookie_userPassWord = $_COOKIE["USERAUTHCODE"];  
  501.             /*通过COOKIE取得用户信息 end*/  
  502.             if(!empty($_cookie_userName) && !empty($_cookie_userPassWord)) {  
  503.                 /* 判断用户是不是在UCENTER中存在,如果不存在则插入一条数据同步到DIS论坛用户 START */  
  504.                 /* 用COOKIE用户名称检索UCENTER */  
  505.                 $query = DB::query("SELECT uid FROM ".DB::table('ucenter_members')." WHERE username = '$_cookie_userName' limit 1");  
  506.                 if(!DB::num_rows($query)) {  
  507.                         // 插入用户中心数据  
  508.                         DB::query( "INSERT INTO ".DB::table('ucenter_members')." (uid,username,password,email) VALUES ('$discuz_uid','$_cookie_userName','$_cookie_userPassWord','')");  
  509.                         DB::query("commit;");  
  510.                         $query = DB::query("SELECT uid FROM ".DB::table('ucenter_members')." WHERE username = '$_cookie_userName' limit 1");  
  511.                         $discuz_uid = DB::result($query, 0);  
  512.                         DB::query( "INSERT INTO ".DB::table('ucenter_memberfields')."(uid) VALUES ('$discuz_uid')");  
  513.                         DB::query("commit;");  
  514.                         /* 这个取得公用主键ID  创建UCENTER中用户,在DIS中再检索处理 */  
  515.                         /* 取得论坛用户UID */  
  516.                         $query = DB::query("SELECT uid FROM ".DB::table("common_member")." WHERE username = '$_cookie_userName' limit 1");  
  517.                         if(DB::num_rows($query)) {  
  518.                             $discuz_uid = DB::result($query, 0);  
  519.                         } else {  
  520.                             // 同步插入论坛数据  
  521.                             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','')");  
  522.                             DB::query( "INSERT INTO ".DB::table('common_member_status')." (uid) VALUES ('$discuz_uid')");  
  523.                             DB::query( "INSERT INTO ".DB::table('common_member_profile')."(uid)value('$discuz_uid')");  
  524.                             DB::query( "INSERT INTO ".DB::table('common_member_field_forum')."(uid)value('$discuz_uid')");  
  525.                             DB::query( "INSERT INTO ".DB::table('common_member_field_home')."(uid)VALUE('$discuz_uid')");  
  526.                             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')");  
  527.                             DB::query("commit;");  
  528.                             $query = DB::query("SELECT uid FROM ".DB::table("common_member")." WHERE username = '$_cookie_userName' limit 1");  
  529.                             $discuz_uid = DB::result($query, 0);  
  530.                         }  
  531.                         // 取得登录用户信息,写入COOKIE  
  532.                         $user = getuserbyuid($discuz_uid);  
  533.                         $ucsynlogin = $this->setting['allowsynlogin'] ? uc_user_synlogin($discuz_uid) : '';  
  534.                         $this->var['member'] = $user;  
  535.             } else {  
  536.                     // 取得登录用户信息,写入COOKIE  
  537.                         $discuz_uid = DB::result($query, 0);  
  538.                         DB::query(" UPDATE ".DB::table('ucenter_members')." SET password='".$_cookie_userPassWord."' WHERE uid=".$discuz_uid);  
  539.                         DB::query(" UPDATE ".DB::table('common_member')." SET password='".$_cookie_userPassWord."' WHERE uid=".$discuz_uid);  
  540.                         DB::query("commit;");  
  541.                         $user = getuserbyuid($discuz_uid);  
  542.                         //var_dump($discuz_uid);  
  543.                         $ucsynlogin = $this->setting['allowsynlogin'] ? uc_user_synlogin($discuz_uid) : '';  
  544.                         //var_dump($ucsynlogin);  
  545.                     $this->var['member'] = $user;  
  546.             }  
  547. /*判断用户是不是在UCENTER中存在,如果不存在则插入一条数据同步到DIS论坛用户 END */  
  548.             } else {  
  549.                 /*判断是否UC用户 来源CDB start*/  
  550.                 if($auth = getglobal('auth', 'cookie')) {//得到auth,auth的值:"username\tuid"的加密信息  
  551.                                         //进行解密  
  552.                     $auth = daddslashes(explode("\t", authcode($auth, 'DECODE')));  
  553.                 }  
  554.                                 //得到用户名和用户密码,如果auth为空,或者确实uid和username中的一个,则为空  
  555.                 list($discuz_pw, $discuz_uid) = empty($auth) || count($auth) < 2 ? array('', '') : $auth;  
  556.                   
  557.                 if($discuz_uid) {  
  558.                     $user = getuserbyuid($discuz_uid);//如果uid存在,则得到该用户信息  
  559.                 }  
  560.                   
  561.                 if(!empty($user) && $user['password'] == $discuz_pw) {  
  562.                     $this->var['member'] = $user;//如果用户存在且密码正确,则将用户信息写入全局变量中  
  563.                 } else {  
  564.                     /*游客判断 START*/  
  565.                         $user = array();//user定义为空数组  
  566.                         $this->_init_guest();//是否为游客,游客初始化方法  
  567.                     /*游客判断 END*/  
  568.                 }  
  569.               /*判断是否UC用户 来源CDB end*/  
  570.             }  
  571.                       
  572.                         //用户组过期检测  
  573.             if($user && $user['groupexpiry'] > 0 && $user['groupexpiry'] < TIMESTAMP && getgpc('mod') != 'spacecp' && getgpc('do') != 'expiry' && CURSCRIPT != 'home') {  
  574.                 dheader('location: home.php?mod=spacecp&ac=usergroup&do=expiry');  
  575.             }  
  576.   
  577.                         //用户组数据缓存  
  578.             $this->cachelist[] = 'usergroup_'.$this->var['member']['groupid'];  
  579.             if($user && $user['adminid'] > 0 && $user['groupid'] != $user['adminid']) {  
  580.                 $this->cachelist[] = 'admingroup_'.$this->var['member']['adminid'];  
  581.             }  
  582.   
  583.         } else {  
  584.             $this->_init_guest();//游客  
  585.         }  
  586.   
  587.         if(empty($this->var['cookie']['lastvisit'])) {//cookie中如果记录有最后一次访问时间,则写入  
  588.             $this->var['member']['lastvisit'] = TIMESTAMP - 3600;  
  589.             dsetcookie('lastvisit', TIMESTAMP - 3600, 86400 * 30);  
  590.         } else {  
  591.                         //否则写入全局变量  
  592.             $this->var['member']['lastvisit'] = $this->var['cookie']['lastvisit'];  
  593.         }  
  594.         setglobal('uid', getglobal('uid', 'member'));//用户uid  
  595.         setglobal('username', addslashes(getglobal('username', 'member')));//用户名  
  596.         setglobal('adminid', getglobal('adminid', 'member'));//管理组id  
  597.         setglobal('groupid', getglobal('groupid', 'member'));//用户组id  
  598.     }  
  599.   
  600.         /* 
  601.          * 1、初始化当前用户信息为游客 
  602.          */  
  603.     function _init_guest() {  
  604.         setglobal('member', array( 'uid' => 0, 'username' => '', 'adminid' => 0, 'groupid' => 7, 'credits' => 0, 'timeoffset' => 9999));  
  605.     }  
  606.   
  607.         /* 
  608.          * 1、处理计划任务 
  609.          */  
  610.     function _init_cron() {  
  611.         $ext = empty($this->config['remote']['on']) || empty($this->config['remote']['cron']) || APPTYPEID == 200;  
  612.         if($this->init_cron && $this->init_setting && $ext) {  
  613.             if($this->var['cache']['cronnextrun'] <= TIMESTAMP) {  
  614.                 require_once libfile('class/cron');//加载"/source/class/class_cron.php"文件  
  615.                 discuz_cron::run();//运行  
  616.             }  
  617.         }  
  618.     }  
  619.   
  620.         /* 
  621.          * 1、杂项 
  622.          * 2、调入核心语言包 
  623.          * 3、处理全局时区设置 
  624.          * 4、处理被封禁用户 
  625.          * 5、站点开关检查 
  626.          * 6、手机端控制每页显示主题数和回帖数 
  627.          * 7、判断并执行每日登陆奖励积分 
  628.          */  
  629.     function _init_misc() {  
  630.         if(!$this->init_misc) {  
  631.             return false;  
  632.         }  
  633.         lang('core');//加载core语言包  
  634.   
  635.                 //设置用户时区  
  636.         if($this->init_setting && $this->init_user) {  
  637.             if(!isset($this->var['member']['timeoffset']) || $this->var['member']['timeoffset'] == 9999 || $this->var['member']['timeoffset'] === '') {  
  638.                 $this->var['member']['timeoffset'] = $this->var['setting']['timeoffset'];  
  639.             }  
  640.         }  
  641.   
  642.         $timeoffset = $this->init_setting ? $this->var['member']['timeoffset'] : $this->var['setting']['timeoffset'];  
  643.         $this->var['timenow'] = array(  
  644.             'time' => dgmdate(TIMESTAMP),  
  645.             'offset' => $timeoffset >= 0 ? ($timeoffset == 0 ? '' : '+'.$timeoffset) : $timeoffset  
  646.         );  
  647.         $this->timezone_set($timeoffset);  
  648.   
  649.         $this->var['formhash'] = formhash();//得到formhash  
  650.         define('FORMHASH', $this->var['formhash']);//定义为常量  
  651.   
  652.         if($this->init_user) {  
  653.             if($this->var['group'] && isset($this->var['group']['allowvisit']) && !$this->var['group']['allowvisit']) {  
  654.                 if($this->var['uid']) {  
  655.                     sysmessage('user_banned', null);//检测是否为禁止访问  
  656.                 } elseif((!defined('ALLOWGUEST') || !ALLOWGUEST) && !in_array(CURSCRIPT, array('member', 'api')) && !$this->var['inajax']) {  
  657.                     dheader('location: member.php?mod=logging&action=login&referer='.rawurlencode($_SERVER['REQUEST_URI']));  
  658.                 }  
  659.             }  
  660.             if($this->var['member']['status'] == -1) {  
  661.                 sysmessage('user_banned', null);//如果用户状态为-1,则提示禁止访问  
  662.             }  
  663.         }  
  664.   
  665.         if($this->var['setting']['ipaccess'] && !ipaccess($this->var['clientip'], $this->var['setting']['ipaccess'])) {  
  666.             sysmessage('user_banned', null);//ip权限检测  
  667.         }  
  668.   
  669.                 //如果论坛为关闭,只有管理员可以访问,其他则提示关闭原因  
  670.         if($this->var['setting']['bbclosed']) {  
  671.             if($this->var['uid'] && ($this->var['group']['allowvisit'] == 2 || $this->var['groupid'] == 1)) {  
  672.             } elseif(in_array(CURSCRIPT, array('admin', 'member', 'api')) || defined('ALLOWGUEST') && ALLOWGUEST) {  
  673.             } else {  
  674.                 $closedreason = DB::result_first("SELECT svalue FROM ".DB::table('common_setting')." WHERE skey='closedreason'");  
  675.                 $closedreason = str_replace(':', ':', $closedreason);  
  676.                 showmessage($closedreason ? $closedreason : 'board_closed', NULL, array('adminemail' => $this->var['setting']['adminemail']), array('login' => 1));  
  677.             }  
  678.         }  
  679.   
  680.         if(CURSCRIPT != 'admin' && !(in_array($this->var['mod'], array('logging', 'seccode')))) {  
  681.             periodscheck('visitbanperiods');//私密板块访问设置  
  682.         }  
  683.   
  684.                 //wap访问设置  
  685.         if(defined('IN_MOBILE')) {  
  686.             $this->var['tpp'] = $this->var['setting']['mobile']['mobiletopicperpage'] ? intval($this->var['setting']['mobile']['mobiletopicperpage']) : 20;  
  687.             $this->var['ppp'] = $this->var['setting']['mobile']['mobilepostperpage'] ? intval($this->var['setting']['mobile']['mobilepostperpage']) : 5;  
  688.         } else {  
  689.             $this->var['tpp'] = $this->var['setting']['topicperpage'] ? intval($this->var['setting']['topicperpage']) : 20;  
  690.             $this->var['ppp'] = $this->var['setting']['postperpage'] ? intval($this->var['setting']['postperpage']) : 10;  
  691.         }  
  692.   
  693.                 //header头信息设置  
  694.         if($this->var['setting']['nocacheheaders']) {  
  695.             @header("Expires: -1");  
  696.             @header("Cache-Control: no-store, private, post-check=0, pre-check=0, max-age=0", FALSE);  
  697.             @header("Pragma: no-cache");  
  698.         }  
  699.   
  700.         if($this->session->isnew && $this->var['uid']) {  
  701.             updatecreditbyaction('daylogin', $this->var['uid']);//每日登陆增加积分设置  
  702.   
  703.             include_once libfile('function/stat');  
  704.             updatestat('login', 1);  
  705.             if(defined('IN_MOBILE')) {  
  706.                 updatestat('mobilelogin', 1);  
  707.             }  
  708.             if($this->var['setting']['connect']['allow'] && $this->var['member']['conisbind']) {  
  709.                 updatestat('connectlogin', 1);  
  710.             }  
  711.         }  
  712.         if($this->var['member']['conisbind'] && $this->var['setting']['connect']['newbiespan'] !== '') {  
  713.             $this->var['setting']['newbiespan'] = $this->var['setting']['connect']['newbiespan'];  
  714.         }  
  715.   
  716.         $lastact = TIMESTAMP."\t".htmlspecialchars(basename($this->var['PHP_SELF']))."\t".htmlspecialchars($this->var['mod']);  
  717.         dsetcookie('lastact', $lastact, 86400);  
  718.         setglobal('currenturl_encode', base64_encode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']));  
  719.   
  720.         if((!empty($this->var['gp_fromuid']) || !empty($this->var['gp_fromuser'])) && ($this->var['setting']['creditspolicy']['promotion_visit'] || $this->var['setting']['creditspolicy']['promotion_register'])) {  
  721.             require_once libfile('misc/promotion', 'include');  
  722.         }  
  723.   
  724.                 //SEO关键词、描述  
  725.         $this->var['seokeywords'] = !empty($this->var['setting']['seokeywords'][CURSCRIPT]) ? $this->var['setting']['seokeywords'][CURSCRIPT] : '';  
  726.         $this->var['seodescription'] = !empty($this->var['setting']['seodescription'][CURSCRIPT]) ? $this->var['setting']['seodescription'][CURSCRIPT] : '';  
  727.   
  728.     }  
  729.   
  730.         /* 
  731.          * 1、加载全局设置 setting 、风格 style 、 下一个任务 cronnextrun 
  732.          */  
  733.     function _init_setting() {  
  734.         if($this->init_setting) {  
  735.             if(empty($this->var['setting'])) {  
  736.                 $this->cachelist[] = 'setting';//缓存设置文件  
  737.             }  
  738.   
  739.             if(empty($this->var['style'])) {  
  740.                 $this->cachelist[] = 'style_default';//风格缓存设置  
  741.             }  
  742.   
  743.             if(!isset($this->var['cache']['cronnextrun'])) {  
  744.                 $this->cachelist[] = 'cronnextrun';//缓存计划任务  
  745.             }  
  746.         }  
  747.   
  748.         !empty($this->cachelist) && loadcache($this->cachelist);  
  749.   
  750.         if(!is_array($this->var['setting'])) {  
  751.             $this->var['setting'] = array();  
  752.         }  
  753.   
  754.         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']])) {  
  755.             $this->var['group'] = array_merge($this->var['group'], $this->var['cache']['admingroup_'.$this->var['member']['adminid']]);  
  756.         }  
  757.     }  
  758.   
  759.         /* 
  760.          * 1、处理当前界面风格 
  761.          * 2、定义风格常量 
  762.          */  
  763.     function _init_style() {  
  764.         $styleid = !empty($this->var['cookie']['styleid']) ? $this->var['cookie']['styleid'] : 0;  
  765.         if(intval(!empty($this->var['forum']['styleid']))) {  
  766.             $this->var['cache']['style_default']['styleid'] = $styleid = $this->var['forum']['styleid'];  
  767.         } elseif(intval(!empty($this->var['category']['styleid']))) {  
  768.             $this->var['cache']['style_default']['styleid'] = $styleid = $this->var['category']['styleid'];  
  769.         }  
  770.   
  771.         $styleid = intval($styleid);  
  772.   
  773.         if($styleid && $styleid != $this->var['setting']['styleid']) {  
  774.             loadcache('style_'.$styleid);  
  775.             if($this->var['cache']['style_'.$styleid]) {  
  776.                 $this->var['style'] = $this->var['cache']['style_'.$styleid];  
  777.             }  
  778.         }  
  779.   
  780.         define('IMGDIR', $this->var['style']['imgdir']);  
  781.         define('STYLEID', $this->var['style']['styleid']);  
  782.         define('VERHASH', $this->var['style']['verhash']);  
  783.         define('TPLDIR', $this->var['style']['tpldir']);  
  784.         define('TEMPLATEID', $this->var['style']['templateid']);  
  785.     }  
  786.   
  787.         //初始化discuz内存读写引擎  
  788.     function _init_memory() {  
  789.         $this->mem = new discuz_memory();  
  790.         if($this->init_memory) {  
  791.             $this->mem->init($this->config['memory']);  
  792.         }  
  793.         $this->var['memory'] = $this->mem->type;  
  794.     }  
  795.         //手机访问设置  
  796.     function _init_mobile() {  
  797.         if(!$this->var['setting'] || !$this->init_mobile || !$this->var['setting']['mobile']['allowmobile'] || !is_array($this->var['setting']['mobile']) || IS_ROBOT) {  
  798.             $nomobile = true;//允许手机访问  
  799.             $unallowmobile = true;  
  800.         }  
  801.   
  802.         if($_GET['mobile'] === 'no') {  
  803.             dsetcookie('mobile', 'no', 3600);  
  804.             $nomobile = true;  
  805.         } elseif($this->var['cookie']['mobile'] == 'no' && $_GET['mobile'] === 'yes') {  
  806.             dsetcookie('mobile', '');  
  807.         } elseif($this->var['cookie']['mobile'] == 'no') {  
  808.             $nomobile = true;  
  809.         }  
  810.   
  811.         if(!checkmobile()) {//检测是否为手机访问  
  812.             $nomobile = true;  
  813.         }  
  814.   
  815.         if($this->var['setting']['mobile']['mobilepreview'] && !$this->var['mobile'] && !$unallowmobile) {  
  816.             if($_GET['mobile'] === 'yes') {  
  817.                 dheader("Location:misc.php?mod=mobile");  
  818.             }  
  819.         }  
  820.   
  821.         if($nomobile || (!$this->var['setting']['mobile']['mobileforward'] && $_GET['mobile'] !== 'yes')) {  
  822.             if($_SERVER['HTTP_HOST'] == $this->var['setting']['domain']['app']['mobile'] && $this->var['setting']['domain']['app']['default']) {  
  823.                 dheader("Location:http://".$this->var['setting']['domain']['app']['default'].$_SERVER['REQUEST_URI']);  
  824.             } else {  
  825.                 return;  
  826.             }  
  827.         }  
  828.   
  829.         if(strpos($this->var['setting']['domain']['defaultindex'], CURSCRIPT) !== false && CURSCRIPT != 'forum' && !$_GET['mod']) {  
  830.             if($this->var['setting']['domain']['app']['mobile']) {  
  831.                 $mobileurl = 'http://'.$this->var['setting']['domain']['app']['mobile'];  
  832.             } else {  
  833.                 if($this->var['setting']['domain']['app']['forum']) {  
  834.                     $mobileurl = 'http://'.$this->var['setting']['domain']['app']['forum'].'?mobile=yes';  
  835.                 } else {  
  836.                     $mobileurl = $this->var['siteurl'].'forum.php?mobile=yes';  
  837.                 }  
  838.             }  
  839.             dheader("location:$mobileurl");  
  840.         }  
  841.         define('IN_MOBILE', true);  
  842.         setglobal('gzipcompress', 0);  
  843.   
  844.         $arr = array(strstr($_SERVER['QUERY_STRING'], '&simpletype'), strstr($_SERVER['QUERY_STRING'], 'simpletype'), '&mobile=yes', 'mobile=yes');  
  845.         $query_sting_tmp = str_replace($arr, '', $_SERVER['QUERY_STRING']);  
  846.         $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';  
  847.   
  848.         $this->var['setting']['lazyload'] = 0;  
  849.   
  850.         if('utf-8' != CHARSET) {  
  851.             if(strtolower($_SERVER['REQUEST_METHOD']) === 'post') {  
  852.                 foreach($_POST AS $pk => $pv) {  
  853.                     if(!is_numeric($pv)) {  
  854.                         $this->var['gp_'.$pk] = $_GET[$pk] = $_POST[$pk] = $this->mobile_iconv_recurrence($pv);  
  855.                     }  
  856.                 }  
  857.             }  
  858.         }  
  859.   
  860.         if($_GET['simpletype']) {  
  861.             if($_GET['simpletype'] == 'yes') {  
  862.                 $this->var['setting']['mobile']['mobilesimpletype'] = 1;  
  863.                 dsetcookie('simpletype', 1, 86400);  
  864.             } else {  
  865.                 $this->var['setting']['mobile']['mobilesimpletype'] = 0;  
  866.                 dsetcookie('simpletype', 0, 86400);  
  867.             }  
  868.         } elseif($this->var['cookie']['simpletype']) {  
  869.             $this->var['setting']['mobile']['mobilesimpletype'] = $this->var['cookie']['simpletype'] == 1 ? 1 : 0 ;  
  870.         }  
  871.   
  872.         if(!$this->var['setting']['mobile']['mobilesimpletype']) {  
  873.             $this->var['setting']['imagemaxwidth'] = 224;  
  874.         }  
  875.   
  876.         $this->var['setting']['regstatus'] = $this->var['setting']['mobile']['mobileregister'] ? $this->var['setting']['regstatus'] : 0 ;  
  877.         if(!$this->var['setting']['mobile']['mobileseccode']) {  
  878.             $this->var['setting']['seccodestatus'] = 0;  
  879.         }  
  880.   
  881.         $this->var['setting']['seccodedata']['type'] = 99;  
  882.         $this->var['setting']['thumbquality'] = 50;  
  883.   
  884.   
  885.         $this->var['setting']['mobile']['simpletypeurl'] = array();  
  886.         $this->var['setting']['mobile']['simpletypeurl'][0] = $this->var['siteurl'].$this->var['basefilename'].($query_sting_tmp ? '?'.$query_sting_tmp.'&' : '?').'mobile=yes&simpletype=no';  
  887.         $this->var['setting']['mobile']['simpletypeurl'][1] =  $this->var['siteurl'].$this->var['basefilename'].($query_sting_tmp ? '?'.$query_sting_tmp.'&' : '?').'mobile=yes&simpletype=yes';  
  888.         unset($query_sting_tmp);  
  889.         ob_start();  
  890.     }  
  891.   
  892.         //时区设置  
  893.     function timezone_set($timeoffset = 0) {  
  894.         if(function_exists('date_default_timezone_set')) {  
  895.             @date_default_timezone_set('Etc/GMT'.($timeoffset > 0 ? '-' : '+').(abs($timeoffset)));  
  896.         }  
  897.     }  
  898.   
  899.         //手机访问再次转码  
  900.     function mobile_iconv_recurrence($value) {  
  901.         if(is_array($value)) {  
  902.             foreach($value AS $key => $val) {  
  903.                 $value[$key] = $this->mobile_iconv_recurrence($val);  
  904.             }  
  905.         } else {  
  906.             $value = addslashes(diconv(stripslashes($value), 'utf-8', CHARSET));  
  907.         }  
  908.         return $value;  
  909.     }  
  910. }  
  911.   
  912. /** 
  913.  * Discuz MySQL 类的支持 程序中不直接使用 
  914.  * 
  915.  */  
  916. class db_mysql  
  917. {  
  918.     var $tablepre;  
  919.     var $version = '';  
  920.     var $querynum = 0;  
  921.     var $slaveid = 0;  
  922.     var $curlink;  
  923.     var $link = array();  
  924.     var $config = array();  
  925.     var $sqldebug = array();  
  926.     var $map = array();  
  927.   
  928.     function db_mysql($config = array()) {  
  929.         if(!empty($config)) {  
  930.             $this->set_config($config);  
  931.         }  
  932.     }  
  933.   
  934.     function set_config($config) {  
  935.         $this->config = &$config;  
  936.         $this->tablepre = $config['1']['tablepre'];  
  937.         if(!empty($this->config['map'])) {  
  938.             $this->map = $this->config['map'];  
  939.         }  
  940.     }  
  941.   
  942.     function connect($serverid = 1) {  
  943.   
  944.         if(empty($this->config) || empty($this->config[$serverid])) {  
  945.             $this->halt('config_db_not_found');  
  946.         }  
  947.   
  948.         $this->link[$serverid] = $this->_dbconnect(  
  949.             $this->config[$serverid]['dbhost'],  
  950.             $this->config[$serverid]['dbuser'],  
  951.             $this->config[$serverid]['dbpw'],  
  952.             $this->config[$serverid]['dbcharset'],  
  953.             $this->config[$serverid]['dbname'],  
  954.             $this->config[$serverid]['pconnect']  
  955.             );  
  956.         $this->curlink = $this->link[$serverid];  
  957.   
  958.     }  
  959.   
  960.     function _dbconnect($dbhost, $dbuser, $dbpw, $dbcharset, $dbname, $pconnect) {  
  961.         $link = null;  
  962.         $func = empty($pconnect) ? 'mysql_connect' : 'mysql_pconnect';  
  963.         if(!$link = @$func($dbhost, $dbuser, $dbpw, 1)) {  
  964.             $this->halt('notconnect');  
  965.         } else {  
  966.             $this->curlink = $link;  
  967.             if($this->version() > '4.1') {  
  968.                 $dbcharset = $dbcharset ? $dbcharset : $this->config[1]['dbcharset'];  
  969.                 $serverset = $dbcharset ? 'character_set_connection='.$dbcharset.', character_set_results='.$dbcharset.', character_set_client=binary' : '';  
  970.                 $serverset .= $this->version() > '5.0.1' ? ((empty($serverset) ? '' : ',').'sql_mode=\'\'') : '';  
  971.                 $serverset && mysql_query("SET $serverset", $link);  
  972.             }  
  973.             $dbname && @mysql_select_db($dbname, $link);  
  974.         }  
  975.         return $link;  
  976.     }  
  977.   
  978.     function table_name($tablename) {  
  979.         if(!empty($this->map) && !empty($this->map[$tablename])) {  
  980.             $id = $this->map[$tablename];  
  981.             if(!$this->link[$id]) {  
  982.                 $this->connect($id);  
  983.             }  
  984.             $this->curlink = $this->link[$id];  
  985.             return $this->config[$id]['tablepre'].$tablename;  
  986.         } else {  
  987.             $this->curlink = $this->link[1];  
  988.         }  
  989.         return $this->tablepre.$tablename;  
  990.     }  
  991.   
  992.     function select_db($dbname) {  
  993.         return mysql_select_db($dbname, $this->curlink);  
  994.     }  
  995.   
  996.     function fetch_array($query, $result_type = MYSQL_ASSOC) {  
  997.         return mysql_fetch_array($query, $result_type);  
  998.     }  
  999.   
  1000.     function fetch_first($sql) {  
  1001.         return $this->fetch_array($this->query($sql));  
  1002.     }  
  1003.   
  1004.     function result_first($sql) {  
  1005.         return $this->result($this->query($sql), 0);  
  1006.     }  
  1007.   
  1008.     function query($sql, $type = '') {  
  1009.   
  1010.         if(defined('DISCUZ_DEBUG') && DISCUZ_DEBUG) {  
  1011.             $starttime = dmicrotime();  
  1012.         }  
  1013.         $func = $type == 'UNBUFFERED' && @function_exists('mysql_unbuffered_query') ?  
  1014.         'mysql_unbuffered_query' : 'mysql_query';  
  1015.         if(!($query = $func($sql, $this->curlink))) {  
  1016.             if(in_array($this->errno(), array(2006, 2013)) && substr($type, 0, 5) != 'RETRY') {  
  1017.                 $this->connect();  
  1018.                 return $this->query($sql, 'RETRY'.$type);  
  1019.             }  
  1020.             if($type != 'SILENT' && substr($type, 5) != 'SILENT') {  
  1021.                 $this->halt('query_error', $sql);  
  1022.             }  
  1023.         }  
  1024.   
  1025.         if(defined('DISCUZ_DEBUG') && DISCUZ_DEBUG) {  
  1026.             $this->sqldebug[] = array($sql, number_format((dmicrotime() - $starttime), 6), debug_backtrace());  
  1027.         }  
  1028.   
  1029.         $this->querynum++;  
  1030.         return $query;  
  1031.     }  
  1032.   
  1033.     function affected_rows() {  
  1034.         return mysql_affected_rows($this->curlink);  
  1035.     }  
  1036.   
  1037.     function error() {  
  1038.         return (($this->curlink) ? mysql_error($this->curlink) : mysql_error());  
  1039.     }  
  1040.   
  1041.     function errno() {  
  1042.         return intval(($this->curlink) ? mysql_errno($this->curlink) : mysql_errno());  
  1043.     }  
  1044.   
  1045.     function result($query, $row = 0) {  
  1046.         $query = @mysql_result($query, $row);  
  1047.         return $query;  
  1048.     }  
  1049.   
  1050.     function num_rows($query) {  
  1051.         $query = mysql_num_rows($query);  
  1052.         return $query;  
  1053.     }  
  1054.   
  1055.     function num_fields($query) {  
  1056.         return mysql_num_fields($query);  
  1057.     }  
  1058.   
  1059.     function free_result($query) {  
  1060.         return mysql_free_result($query);  
  1061.     }  
  1062.   
  1063.     function insert_id() {  
  1064.         return ($id = mysql_insert_id($this->curlink)) >= 0 ? $id : $this->result($this->query("SELECT last_insert_id()"), 0);  
  1065.     }  
  1066.   
  1067.     function fetch_row($query) {  
  1068.         $query = mysql_fetch_row($query);  
  1069.         return $query;  
  1070.     }  
  1071.   
  1072.     function fetch_fields($query) {  
  1073.         return mysql_fetch_field($query);  
  1074.     }  
  1075.   
  1076.     function version() {  
  1077.         if(empty($this->version)) {  
  1078.             $this->version = mysql_get_server_info($this->curlink);  
  1079.         }  
  1080.         return $this->version;  
  1081.     }  
  1082.   
  1083.     function close() {  
  1084.         return mysql_close($this->curlink);  
  1085.     }  
  1086.   
  1087.     function halt($message = '', $sql = '') {  
  1088.         require_once libfile('class/error');  
  1089.         discuz_error::db_error($message, $sql);  
  1090.     }  
  1091.   
  1092. }  
  1093.   
  1094. /** 
  1095.  * 对Discuz CORE 中 DB Object中的主要方法进行二次封装,方便程序调用 
  1096.  * 
  1097.  */  
  1098. class DB  
  1099. {  
  1100.   
  1101.         /** 
  1102.      * 返回表名(pre_$table) 
  1103.      * 
  1104.      * @param 原始表名 $table 
  1105.      * @return 增加pre之后的名字 
  1106.      */  
  1107.     function table($table) {  
  1108.         return DB::_execute('table_name', $table);  
  1109.     }  
  1110.   
  1111.         /** 
  1112.      * 删除一条或者多条记录 
  1113.      * 
  1114.      * @param string $table 原始表名 
  1115.      * @param string $condition 条件语句,不需要写WHERE 
  1116.      * @param int $limit 删除条目数 
  1117.      * @param boolean $unbuffered 立即返回? 
  1118.      */  
  1119.     function delete($table, $condition, $limit = 0, $unbuffered = true) {  
  1120.         if(empty($condition)) {  
  1121.             $where = '1';  
  1122.         } elseif(is_array($condition)) {  
  1123.             $where = DB::implode_field_value($condition, ' AND ');  
  1124.         } else {  
  1125.             $where = $condition;  
  1126.         }  
  1127.         $sql = "DELETE FROM ".DB::table($table)." WHERE $where ".($limit ? "LIMIT $limit" : '');  
  1128.         return DB::query($sql, ($unbuffered ? 'UNBUFFERED' : ''));  
  1129.     }  
  1130.   
  1131.         /** 
  1132.      * 插入一条记录 
  1133.      * 
  1134.      * @param string $table 原始表名 
  1135.      * @param array $data 数组field->vlaue 对 
  1136.      * @param boolen $return_insert_id 返回 InsertID? 
  1137.      * @param boolen $replace 是否是REPLACE模式 
  1138.      * @param boolen $silent 屏蔽错误? 
  1139.      * @return InsertID or Result 
  1140.      */  
  1141.     function insert($table, $data, $return_insert_id = false, $replace = false, $silent = false) {  
  1142.   
  1143.         $sql = DB::implode_field_value($data);  
  1144.   
  1145.         $cmd = $replace ? 'REPLACE INTO' : 'INSERT INTO';  
  1146.   
  1147.         $table = DB::table($table);  
  1148.         $silent = $silent ? 'SILENT' : '';  
  1149.   
  1150.         $return = DB::query("$cmd $table SET $sql", $silent);  
  1151.   
  1152.         return $return_insert_id ? DB::insert_id() : $return;  
  1153.   
  1154.     }  
  1155.   
  1156.         /** 
  1157.      * 更新一条或者多条数据记录 
  1158.      * 
  1159.      * @param string $table 原始表名 
  1160.      * @param array $data 数据field-value 
  1161.      * @param string $condition 条件语句,不需要写WHERE 
  1162.      * @param boolean $unbuffered 迅速返回? 
  1163.      * @param boolan $low_priority 延迟更新? 
  1164.      * @return result 
  1165.      */  
  1166.     function update($table, $data, $condition, $unbuffered = false, $low_priority = false) {  
  1167.         $sql = DB::implode_field_value($data);  
  1168.         $cmd = "UPDATE ".($low_priority ? 'LOW_PRIORITY' : '');  
  1169.         $table = DB::table($table);  
  1170.         $where = '';  
  1171.         if(empty($condition)) {  
  1172.             $where = '1';  
  1173.         } elseif(is_array($condition)) {  
  1174.             $where = DB::implode_field_value($condition, ' AND ');  
  1175.         } else {  
  1176.             $where = $condition;  
  1177.         }  
  1178.         $res = DB::query("$cmd $table SET $sql WHERE $where", $unbuffered ? 'UNBUFFERED' : '');  
  1179.         return $res;  
  1180.     }  
  1181.   
  1182.         /** 
  1183.      * 格式化field字段和value,并组成一个字符串 
  1184.      * 
  1185.      * @param array $array 格式为 key=>value 数组 
  1186.      * @param 分割符 $glue 
  1187.      * @return string 
  1188.      */  
  1189.     function implode_field_value($array, $glue = ',') {  
  1190.         $sql = $comma = '';  
  1191.         foreach ($array as $k => $v) {  
  1192.             $sql .= $comma."`$k`='$v'";  
  1193.             $comma = $glue;  
  1194.         }  
  1195.         return $sql;  
  1196.     }  
  1197.   
  1198.         /** 
  1199.      * 返回插入的ID 
  1200.      * 
  1201.      * @return int 
  1202.      */  
  1203.     function insert_id() {  
  1204.         return DB::_execute('insert_id');  
  1205.     }  
  1206.   
  1207.         /** 
  1208.      * 依据查询结果,返回一行数据 
  1209.      * 
  1210.      * @param resourceID $resourceid 
  1211.      * @return array 
  1212.      */  
  1213.     function fetch($resourceid, $type = MYSQL_ASSOC) {  
  1214.         return DB::_execute('fetch_array', $resourceid, $type);  
  1215.     }  
  1216.   
  1217.         /** 
  1218.      * 依据SQL语句,返回第一条查询结果 
  1219.      * 
  1220.      * @param string $query 查询语句 
  1221.      * @return array 
  1222.      */  
  1223.     function fetch_first($sql) {  
  1224.         DB::checkquery($sql);  
  1225.         return DB::_execute('fetch_first', $sql);  
  1226.     }  
  1227.   
  1228.         /** 
  1229.      * 依据查询结果,返回结果数值 
  1230.      * 
  1231.      * @param resourceid $resourceid 
  1232.      * @return string or int 
  1233.      */  
  1234.     function result($resourceid, $row = 0) {  
  1235.         return DB::_execute('result', $resourceid, $row);  
  1236.     }  
  1237.   
  1238.         /** 
  1239.      * 依据查询语句,返回结果数值 
  1240.      * 
  1241.      * @param string $query SQL查询语句 
  1242.      * @return unknown 
  1243.      */  
  1244.     function result_first($sql) {  
  1245.         DB::checkquery($sql);  
  1246.         return DB::_execute('result_first', $sql);  
  1247.     }  
  1248.   
  1249.         /** 
  1250.      * 执行查询 
  1251.      * 
  1252.      * @param string $sql 
  1253.      * @param 类型定义 $type UNBUFFERED OR SILENT 
  1254.      * @return Resource OR Result 
  1255.      */  
  1256.     function query($sql, $type = '') {  
  1257.         DB::checkquery($sql);  
  1258.         return DB::_execute('query', $sql, $type);  
  1259.     }  
  1260.   
  1261.         /** 
  1262.      * 返回select的结果行数 
  1263.      * 
  1264.      * @param resource $resourceid 
  1265.      * @return int 
  1266.      */  
  1267.     function num_rows($resourceid) {  
  1268.         return DB::_execute('num_rows', $resourceid);  
  1269.     }  
  1270.   
  1271.         /** 
  1272.      * 返回sql语句所影响的记录行数 
  1273.      * 
  1274.      * @return int 
  1275.      */  
  1276.     function affected_rows() {  
  1277.         return DB::_execute('affected_rows');  
  1278.     }  
  1279.   
  1280.     function free_result($query) {  
  1281.         return DB::_execute('free_result', $query);  
  1282.     }  
  1283.   
  1284.     function error() {  
  1285.         return DB::_execute('error');  
  1286.     }  
  1287.   
  1288.     function errno() {  
  1289.         return DB::_execute('errno');  
  1290.     }  
  1291.   
  1292.     function _execute($cmd , $arg1 = '', $arg2 = '') {  
  1293.         static $db;  
  1294.         if(empty($db)) $db = & DB::object();  
  1295.         $res = $db->$cmd($arg1, $arg2);  
  1296.         return $res;  
  1297.     }  
  1298.   
  1299.         /** 
  1300.      * 返回 DB object 指针 
  1301.      * 
  1302.      * @return pointer of db object from discuz core 
  1303.      */  
  1304.     function &object($dbclass = 'db_mysql') {  
  1305.         static $db;  
  1306.         if(empty($db)) $db = new $dbclass();  
  1307.         return $db;  
  1308.     }  
  1309.   
  1310.     function checkquery($sql) {  
  1311.         static $status = null, $checkcmd = array('SELECT', 'UPDATE', 'INSERT', 'REPLACE', 'DELETE');  
  1312.         if($status === null) $status = getglobal('config/security/querysafe/status');  
  1313.         if($status) {  
  1314.             $cmd = trim(strtoupper(substr($sql, 0, strpos($sql, ' '))));  
  1315.             if(in_array($cmd, $checkcmd)) {  
  1316.                 $test = DB::_do_query_safe($sql);  
  1317.                 if($test < 1) DB::_execute('halt', 'security_error', $sql);  
  1318.             }  
  1319.         }  
  1320.         return true;  
  1321.     }  
  1322.   
  1323.     function _do_query_safe($sql) {  
  1324.         static $_CONFIG = null;  
  1325.         if($_CONFIG === null) {  
  1326.             $_CONFIG = getglobal('config/security/querysafe');  
  1327.         }  
  1328.   
  1329.         $sql = str_replace(array('\\\\', '\\\'', '\\"', '\'\''), '', $sql);  
  1330.         $mark = $clean = '';  
  1331.         if(strpos($sql, '/') === false && strpos($sql, '#') === false && strpos($sql, '-- ') === false) {  
  1332.             $clean = preg_replace("/'(.+?)'/s", '', $sql);  
  1333.         } else {  
  1334.             $len = strlen($sql);  
  1335.             $mark = $clean = '';  
  1336.             for ($i = 0; $i <$len; $i++) {  
  1337.                 $str = $sql[$i];  
  1338.                 switch ($str) {  
  1339.                     case '\'':  
  1340.                         if(!$mark) {  
  1341.                             $mark = '\'';  
  1342.                             $clean .= $str;  
  1343.                         } elseif ($mark == '\'') {  
  1344.                             $mark = '';  
  1345.                         }  
  1346.                         break;  
  1347.                     case '/':  
  1348.                         if(empty($mark) && $sql[$i+1] == '*') {  
  1349.                             $mark = '/*';  
  1350.                             $clean .= $mark;  
  1351.                             $i++;  
  1352.                         } elseif($mark == '/*' && $sql[$i -1] == '*') {  
  1353.                             $mark = '';  
  1354.                             $clean .= '*';  
  1355.                         }  
  1356.                         break;  
  1357.                     case '#':  
  1358.                         if(empty($mark)) {  
  1359.                             $mark = $str;  
  1360.                             $clean .= $str;  
  1361.                         }  
  1362.                         break;  
  1363.                     case "\n":  
  1364.                         if($mark == '#' || $mark == '--') {  
  1365.                             $mark = '';  
  1366.                         }  
  1367.                         break;  
  1368.                     case '-':  
  1369.                         if(empty($mark)&& substr($sql, $i, 3) == '-- ') {  
  1370.                             $mark = '-- ';  
  1371.                             $clean .= $mark;  
  1372.                         }  
  1373.                         break;  
  1374.   
  1375.                     default:  
  1376.   
  1377.                         break;  
  1378.                 }  
  1379.                 $clean .= $mark ? '' : $str;  
  1380.             }  
  1381.         }  
  1382.   
  1383.         $clean = preg_replace("/[^a-z0-9_\-#\*\/\"]+/is", "", strtolower($clean));  
  1384.   
  1385.         if($_CONFIG['afullnote']) {  
  1386.             $clean = str_replace('/**/','',$clean);  
  1387.         }  
  1388.   
  1389.         if(is_array($_CONFIG['dfunction'])) {  
  1390.             foreach($_CONFIG['dfunction'] as $fun) {  
  1391.                 if(strpos($clean, $fun.'(') !== false) return '-1';  
  1392.             }  
  1393.         }  
  1394.   
  1395.         if(is_array($_CONFIG['daction'])) {  
  1396.             foreach($_CONFIG['daction'] as $action) {  
  1397.                 if(strpos($clean,$action) !== false) return '-3';  
  1398.             }  
  1399.         }  
  1400.   
  1401.         if($_CONFIG['dlikehex'] && strpos($clean, 'like0x')) {  
  1402.             return '-2';  
  1403.         }  
  1404.   
  1405.         if(is_array($_CONFIG['dnote'])) {  
  1406.             foreach($_CONFIG['dnote'] as $note) {  
  1407.                 if(strpos($clean,$note) !== false) return '-4';  
  1408.             }  
  1409.         }  
  1410.   
  1411.         return 1;  
  1412.   
  1413.     }  
  1414.   
  1415. }  
  1416.   
  1417. //session类  
  1418. class discuz_session {  
  1419.   
  1420.     var $sid = null;  
  1421.     var $var;  
  1422.     var $isnew = false;  
  1423.         //初始化session数组  
  1424.     var $newguest = array('sid' => 0, 'ip1' => 0, 'ip2' => 0, 'ip3' => 0, 'ip4' => 0,  
  1425.     'uid' => 0, 'username' => '', 'groupid' => 7, 'invisible' => 0, 'action' => 0,  
  1426.     'lastactivity' => 0, 'fid' => 0, 'tid' => 0, 'lastolupdate' => 0);  
  1427.   
  1428.     var $old =  array('sid' =>  '', 'ip' =>  '', 'uid' =>  0);  
  1429.   
  1430.     function discuz_session($sid = '', $ip = '', $uid = 0) {  
  1431.         $this->old = array('sid' =>  $sid, 'ip' =>  $ip, 'uid' =>  $uid);  
  1432.         $this->var = $this->newguest;  
  1433.         if(!empty($ip)) {  
  1434.             $this->init($sid, $ip, $uid);  
  1435.         }  
  1436.     }  
  1437.   
  1438.         //设置  
  1439.     function set($key, $value) {  
  1440.         if(isset($this->newguest[$key])) {  
  1441.             $this->var[$key] = $value;  
  1442.         } elseif ($key == 'ip') {  
  1443.             $ips = explode('.', $value);  
  1444.             $this->set('ip1', $ips[0]);  
  1445.             $this->set('ip2', $ips[1]);  
  1446.             $this->set('ip3', $ips[2]);  
  1447.             $this->set('ip4', $ips[3]);  
  1448.         }  
  1449.     }  
  1450.   
  1451.         //获取  
  1452.     function get($key) {  
  1453.         if(isset($this->newguest[$key])) {  
  1454.             return $this->var[$key];  
  1455.         } elseif ($key == 'ip') {  
  1456.             return $this->get('ip1').'.'.$this->get('ip2').'.'.$this->get('ip3').'.'.$this->get('ip4');  
  1457.         }  
  1458.     }  
  1459.   
  1460.         //初始化  
  1461.     function init($sid, $ip, $uid) {  
  1462.         $this->old = array('sid' =>  $sid, 'ip' =>  $ip, 'uid' =>  $uid);  
  1463.         $session = array();  
  1464.         if($sid) {  
  1465.             $session = DB::fetch_first("SELECT * FROM ".DB::table('common_session').  
  1466.                 " WHERE sid='$sid' AND CONCAT_WS('.', ip1,ip2,ip3,ip4)='$ip'");  
  1467.         }  
  1468.   
  1469.         if(empty($session) || $session['uid'] != $uid) {  
  1470.             $session = $this->create($ip, $uid);  
  1471.         }  
  1472.   
  1473.         $this->var = $session;  
  1474.         $this->sid = $session['sid'];  
  1475.     }  
  1476.   
  1477.         //创建  
  1478.     function create($ip, $uid) {  
  1479.   
  1480.         $this->isnew = true;  
  1481.         $this->var = $this->newguest;  
  1482.         $this->set('sid', random(6));  
  1483.         $this->set('uid', $uid);  
  1484.         $this->set('ip', $ip);  
  1485.         $uid && $this->set('invisible', getuserprofile('invisible'));  
  1486.         $this->set('lastactivity', time());  
  1487.         $this->sid = $this->var['sid'];  
  1488.   
  1489.         return $this->var;  
  1490.     }  
  1491.   
  1492.         //删除  
  1493.     function delete() {  
  1494.   
  1495.         global $_G;  
  1496.         $onlinehold = $_G['setting']['onlinehold'];  
  1497.         $guestspan = 60;  
  1498.   
  1499.         $onlinehold = time() - $onlinehold;  
  1500.         $guestspan = time() - $guestspan;  
  1501.   
  1502.         $condition = " sid='{$this->sid}' ";  
  1503.         $condition .= " OR lastactivity<$onlinehold ";  
  1504.         $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) ";  
  1505.         $condition .= $this->var['uid'] ? " OR (uid='{$this->var['uid']}') " : '';  
  1506.         DB::delete('common_session', $condition);  
  1507.     }  
  1508.   
  1509.         //更新数据  
  1510.     function update() {  
  1511.         global $_G;  
  1512.         if($this->sid !== null) {  
  1513.   
  1514.             $data = daddslashes($this->var);  
  1515.             if($this->isnew) {  
  1516.                 $this->delete();  
  1517.                 DB::insert('common_session', $data, false, false, true);  
  1518.             } else {  
  1519.                 DB::update('common_session', $data, "sid='$data[sid]'");  
  1520.             }  
  1521.             $_G['session'] = $data;  
  1522.             dsetcookie('sid', $this->sid, 86400);  
  1523.         }  
  1524.     }  
  1525.   
  1526.         /** 
  1527.      * 取在线用户数量 
  1528.      * 
  1529.      * @param int $type 0=全部 1=会员 2=游客 
  1530.      * @return int 
  1531.      */  
  1532.     function onlinecount($type = 0) {  
  1533.         $condition = $type == 1 ? ' WHERE uid>0 ' : ($type == 2 ? ' WHERE invisible=1 ' : '');  
  1534.         return DB::result_first("SELECT count(*) FROM ".DB::table('common_session').$condition);  
  1535.     }  
  1536.   
  1537. }  
  1538.   
  1539.   
  1540. class discuz_process  
  1541. {  
  1542.     function islocked($process, $ttl = 0) {  
  1543.         $ttl = $ttl < 1 ? 600 : intval($ttl);  
  1544.         if(discuz_process::_status('get', $process)) {  
  1545.             return true;  
  1546.         } else {  
  1547.             return discuz_process::_find($process, $ttl);  
  1548.         }  
  1549.     }  
  1550.   
  1551.     function unlock($process) {  
  1552.         discuz_process::_status('rm', $process);  
  1553.         discuz_process::_cmd('rm', $process);  
  1554.     }  
  1555.   
  1556.     function _status($action, $process) {  
  1557.         static $plist = array();  
  1558.         switch ($action) {  
  1559.             case 'set' : $plist[$process] = true; break;  
  1560.             case 'get' : return !empty($plist[$process]); break;  
  1561.             case 'rm' : $plist[$process] = null; break;  
  1562.             case 'clear' : $plist = array(); break;  
  1563.         }  
  1564.         return true;  
  1565.     }  
  1566.   
  1567.     function _find($name, $ttl) {  
  1568.   
  1569.         if(!discuz_process::_cmd('get', $name)) {  
  1570.             discuz_process::_cmd('set', $name, $ttl);  
  1571.             $ret = false;  
  1572.         } else {  
  1573.             $ret = true;  
  1574.         }  
  1575.         discuz_process::_status('set', $name);  
  1576.         return $ret;  
  1577.     }  
  1578.   
  1579.     function _cmd($cmd, $name, $ttl = 0) {  
  1580.         static $allowmem;  
  1581.         if($allowmem === null) {  
  1582.             $allowmem = memory('check') == 'memcache';  
  1583.         }  
  1584.         if($allowmem) {  
  1585.             return discuz_process::_process_cmd_memory($cmd, $name, $ttl);  
  1586.         } else {  
  1587.             return discuz_process::_process_cmd_db($cmd, $name, $ttl);  
  1588.         }  
  1589.     }  
  1590.   
  1591.     function _process_cmd_memory($cmd, $name, $ttl = 0) {  
  1592.         return memory($cmd, 'process_lock_'.$name, time(), $ttl);  
  1593.     }  
  1594.   
  1595.     function _process_cmd_db($cmd, $name, $ttl = 0) {  
  1596.         $ret = '';  
  1597.         switch ($cmd) {  
  1598.             case 'set':  
  1599.                 $ret = DB::insert('common_process', array('processid' => $name, 'expiry' => time() + $ttl), false, true);  
  1600.                 break;  
  1601.             case 'get':  
  1602.                 $ret = DB::fetch_first("SELECT * FROM ".DB::table('common_process')." WHERE processid='$name'");  
  1603.                 if(empty($ret) || $ret['expiry'] < time()) {  
  1604.                     $ret = false;  
  1605.                 } else {  
  1606.                     $ret = true;  
  1607.                 }  
  1608.                 break;  
  1609.             case 'rm':  
  1610.                 $ret = DB::delete('common_process', "processid='$name' OR expiry<".time());  
  1611.                 break;  
  1612.         }  
  1613.         return $ret;  
  1614.     }  
  1615. }  
  1616.   
  1617. /** 
  1618.  * Discuz 内存读写引擎 
  1619.  * 支持 memcache, eAccelerator, XCache 
  1620.  * 
  1621.  * 使用的时候建议直接利用函数 memory() 
  1622.  */  
  1623. class discuz_memory  
  1624. {  
  1625.     var $config;  
  1626.     var $extension = array();  
  1627.     var $memory;  
  1628.     var $prefix;  
  1629.     var $type;  
  1630.     var $keys;  
  1631.     var $enable = false;  
  1632.   
  1633.         /** 
  1634.      * 确认当前系统支持的内存读写接口 
  1635.      * @return discuz_memory 
  1636.      */  
  1637.     function discuz_memory() {  
  1638.         $this->extension['eaccelerator'] = function_exists('eaccelerator_get');  
  1639.         $this->extension['apc'] = function_exists('apc_fetch');  
  1640.         $this->extension['xcache'] = function_exists('xcache_get');  
  1641.         $this->extension['memcache'] = extension_loaded('memcache');  
  1642.     }  
  1643.   
  1644.         /** 
  1645.      * 依据config当中设置,初始化内存引擎 
  1646.      * @param unknown_type $config 
  1647.      */  
  1648.     function init($config) {  
  1649.   
  1650.         $this->config = $config;  
  1651.         $this->prefix = empty($config['prefix']) ? substr(md5($_SERVER['HTTP_HOST']), 0, 6).'_' : $config['prefix'];  
  1652.         $this->keys = array();  
  1653.   
  1654.         if($this->extension['memcache'] && !empty($config['memcache']['server'])) {  
  1655.             require_once libfile('class/memcache');  
  1656.             $this->memory = new discuz_memcache();  
  1657.             $this->memory->init($this->config['memcache']);  
  1658.             if(!$this->memory->enable) {  
  1659.                 $this->memory = null;  
  1660.             }  
  1661.         }  
  1662.   
  1663.         if(!is_object($this->memory) && $this->extension['eaccelerator'] && $this->config['eaccelerator']) {  
  1664.             require_once libfile('class/eaccelerator');  
  1665.             $this->memory = new discuz_eaccelerator();  
  1666.             $this->memory->init(null);  
  1667.         }  
  1668.   
  1669.         if(!is_object($this->memory) && $this->extension['xcache'] && $this->config['xcache']) {  
  1670.             require_once libfile('class/xcache');  
  1671.             $this->memory = new discuz_xcache();  
  1672.             $this->memory->init(null);  
  1673.         }  
  1674.   
  1675.         if(!is_object($this->memory) && $this->extension['apc'] && $this->config['apc']) {  
  1676.             require_once libfile('class/apc');  
  1677.             $this->memory = new discuz_apc();  
  1678.             $this->memory->init(null);  
  1679.         }  
  1680.   
  1681.         if(is_object($this->memory)) {  
  1682.             $this->enable = true;  
  1683.             $this->type = str_replace('discuz_', '', get_class($this->memory));  
  1684.             $this->keys = $this->get('memory_system_keys');  
  1685.             $this->keys = !is_array($this->keys) ? array() : $this->keys;  
  1686.         }  
  1687.   
  1688.     }  
  1689.   
  1690.         /** 
  1691.      * 读取内存 
  1692.      * 
  1693.      * @param string $key 
  1694.      * @return mix 
  1695.      */  
  1696.     function get($key) {  
  1697.         $ret = null;  
  1698.         if($this->enable) {  
  1699.             $ret = $this->memory->get($this->_key($key));  
  1700.             if(!is_array($ret)) {  
  1701.                 $ret = null;  
  1702.                 if(array_key_exists($key, $this->keys)) {  
  1703.                     unset($this->keys[$key]);  
  1704.                     $this->memory->set($this->_key('memory_system_keys'), array($this->keys));  
  1705.                 }  
  1706.             } else {  
  1707.                 return $ret[0];  
  1708.             }  
  1709.         }  
  1710.         return $ret;  
  1711.     }  
  1712.   
  1713.         /** 
  1714.      * 写入内存 
  1715.      * 
  1716.      * @param string $key 
  1717.      * @param array_string_number $value 
  1718.      * @param int过期时间 $ttl 
  1719.      * @return boolean 
  1720.      */  
  1721.     function set($key, $value, $ttl = 0) {  
  1722.   
  1723.         $ret = null;  
  1724.         if($this->enable) {  
  1725.             $ret = $this->memory->set($this->_key($key), array($value), $ttl);  
  1726.             if($ret) {  
  1727.                 $this->keys[$key] = true;  
  1728.                 $this->memory->set($this->_key('memory_system_keys'), array($this->keys));  
  1729.             }  
  1730.         }  
  1731.         return $ret;  
  1732.     }  
  1733.   
  1734.         /** 
  1735.      * 删除一个内存单元 
  1736.      * @param 键值string $key 
  1737.      * @return boolean 
  1738.      */  
  1739.     function rm($key) {  
  1740.         $ret = null;  
  1741.         if($this->enable) {  
  1742.             $ret = $this->memory->rm($this->_key($key));  
  1743.             unset($this->keys[$key]);  
  1744.             $this->memory->set($this->_key('memory_system_keys'), array($this->keys));  
  1745.         }  
  1746.         return $ret;  
  1747.     }  
  1748.   
  1749.         /** 
  1750.      * 清除当前使用的所有内存 
  1751.      */  
  1752.     function clear() {  
  1753.         if($this->enable && is_array($this->keys)) {  
  1754.             if(method_exists($this->memory, 'clear')) {  
  1755.                 $this->memory->clear();  
  1756.             } else {  
  1757.                 $this->keys['memory_system_keys'] = true;  
  1758.                 foreach ($this->keys as $k => $v) {  
  1759.                     $this->memory->rm($this->_key($k));  
  1760.                 }  
  1761.             }  
  1762.         }  
  1763.         $this->keys = array();  
  1764.         return true;  
  1765.     }  
  1766.   
  1767.         /** 
  1768.      * 内部函数 追加键值前缀 
  1769.      * @param string $str 
  1770.      * @return boolean 
  1771.      */  
  1772.     function _key($str) {  
  1773.         return ($this->prefix).$str;  
  1774.     }  
  1775.   
  1776. }  
  1777.   
  1778. ?>  

posted on 2017-09-09 16:01  alleyonine  阅读(271)  评论(0编辑  收藏  举报

导航