【discuzX2】/source/class/class_core.php文件中核心基础类库中discuz_core类分析
发布时间:2023-09-06 01:09责任编辑:傅花花关键词:class类库
- <?php
- /**
- *[Discuz!](C)2001-2099ComsenzInc.
- *ThisisNOTafreeware,useissubjecttolicenseterms
- *
- *$Id:class_core.php244872011-09-2108:13:57Zmonkey$
- */
- define(‘IN_DISCUZ‘,true);//禁止用户直接通过路径访问
- error_reporting(0);//设置错误级别
- //通用基础类
- classdiscuz_core{
- var$db=null;//数据库db类实例化对象
- var$mem=null;//memcached缓存对象
- var$session=null;//session变量
- var$config=array();//配置信息
- //$_G数组的映射
- var$var=array();//变量数组,将超级全局变量$_G的引用赋值给了$var变量
- //加载缓存数组
- var$cachelist=array();//缓存列表
- //是否初始化
- var$init_setting=true;//初始化设置
- var$init_user=true;//初始化用户信息
- var$init_session=true;//初始化session信息
- var$init_cron=true;
- var$init_misc=true;
- var$init_memory=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,
- );
- //建立唯一的进程
- function&instance(){//单例模式实例化一个discuz_core核心类实例化对象
- static$object;
- if(empty($object)){
- $object=newdiscuz_core();//实例化一个discuz_core对象
- }
- return$object;//返回唯一的一个discuz_core类实例化对象
- }
- //预处理的调用
- functiondiscuz_core(){//构造函数
- $this->_init_env();//初始化环境变量
- $this->_init_config();//初始化配置变量
- $this->_init_input();//初始化输入
- $this->_init_output();//初始化输出
- }
- //核心的初始化
- functioninit(){
- if(!$this->initated){
- $this->_init_db();//数据库操作类实例化对象的初始化
- $this->_init_memory();//初始化memcache
- $this->_init_user();//用户信息初始化
- $this->_init_session();//session操作初始化
- $this->_init_setting();//系统设置初始化
- $this->_init_mobile();//手机功能初始化
- $this->_init_cron();//计划任务初始化
- $this->_init_misc();//其他功能的初始化
- }
- $this->initated=true;//初始化完成的标志
- }
- //定义php环境信息常量和$_G全局变量
- /*
- *1、主要讲$_G变量的引用赋值给$var数组变量
- *2、注意:G变量是程序的全局变量,为了让程序更加高效,减少不必要的数据获取,所以程序特将经常需要用到的变量统一到
- *G变量下,如:用户登录信息、后台设置信息、服务器环境信息、客户端cookies、数据缓存等都存放在G变量里面,在制作
- *模板文件的时只需将G变量打印出来即可获得需要的信息是否在G变量中
- *3、自定义变量:自定义变量是以$开头并且首位为字母或下划线的变量,
- *如:$data、$thread、$post、$forumlist、$threadlist
- *4、类似$_G[‘gp_xxx‘]变量都是get和post过来的数据
- */
- function_init_env(){
- //设置错误级别
- error_reporting(E_ERROR);
- if(PHP_VERSION<‘5.3.0‘){
- set_magic_quotes_runtime(0);//设置set_magic_quotes_runtime
- }
- define(‘DISCUZ_ROOT‘,substr(dirname(__FILE__),0,-12));//定义根目录常量:"d:/wamp/www/discuz/"
- define(‘MAGIC_QUOTES_GPC‘,function_exists(‘get_magic_quotes_gpc‘)&&get_magic_quotes_gpc());//定义MAGIC_QUOTES_GPC常量
- define(‘ICONV_ENABLE‘,function_exists(‘iconv‘));//定义是否支持转码函数常量,如:iconv("gb2312","utf-8","我爱卡");//将gb2312编码转换为utf-8编码
- define(‘MB_ENABLE‘,function_exists(‘mb_convert_encoding‘));//定义是否支持转码函数常量,跟iconv用法差不多,有稍微差异
- define(‘EXT_OBGZIP‘,function_exists(‘ob_gzhandler‘));//缓存输出句柄函数
- define(‘TIMESTAMP‘,time());//定义当前时间戳常量
- $this->timezone_set();//设置时区
- /*
- *1、加载系统核心函数库文件
- *2、条件:常量未定义、系统函数库未加载的情况下报"系统核心函数库文件丢失"的错误,否则加载系统核心函数库文件
- */
- if(!defined(‘DISCUZ_CORE_FUNCTION‘)&&!@include(DISCUZ_ROOT.‘./source/function/function_core.php‘)){
- exit(‘function_core.phpismissing‘);//退出,并报"系统核心函数库文件丢失的错误"
- }
- if(function_exists(‘ini_get‘)){//获取php.ini配置文件中设置的配置信息
- $memorylimit=@ini_get(‘memory_limit‘);//设置内存使用限制
- if($memorylimit&&return_bytes($memorylimit)<33554432&&function_exists(‘ini_set‘)){
- ini_set(‘memory_limit‘,‘128m‘);//如果小于32M,则增加到128M
- }
- }
- define(‘IS_ROBOT‘,checkrobot());//检测机器人
- //$GLOBALS:超全局变量,全局作用域中始终可用的内置变量,在函数和方法中无需使用global$xxx声明
- foreach($GLOBALSas$key=>$value){
- if(!isset($this->superglobal[$key])){//注销没有在$superglobal中出现的超全局变量,也就是注销所有的超级全局变量
- $GLOBALS[$key]=null;unset($GLOBALS[$key]);//设置为null并销毁
- }
- }
- //超级变量大数组$_G的定义,在模板文件中要使用
- global$_G;//函数体外可以使用,注意:只能在本文件中,或者include的文件中使用,并不能再整个网站中使用
- $_G=array(
- ‘uid‘=>0,//作者UID
- ‘username‘=>‘‘,//用户名
- ‘adminid‘=>0,//管理组ID
- ‘groupid‘=>1,//用户组ID
- ‘sid‘=>‘‘,//cookie和session相关的sid
- ‘formhash‘=>‘‘,//表单验证认证
- ‘timestamp‘=>TIMESTAMP,//时间戳
- ‘starttime‘=>dmicrotime(),//开始时间
- ‘clientip‘=>$this->_get_client_ip(),//客户端ip
- ‘referer‘=>‘‘,//来路
- ‘charset‘=>‘‘,//字符编码设置
- ‘gzipcompress‘=>‘‘,//gzip
- ‘authkey‘=>‘‘,//密钥
- ‘timenow‘=>array(),
- ‘PHP_SELF‘=>‘‘,//当前php脚本文件,如:"/discuz/forum.php"
- ‘siteurl‘=>‘‘,//站点url
- ‘siteroot‘=>‘‘,//站点根目录
- ‘siteport‘=>‘‘,//站点端口
- ‘config‘=>array(),//配置变量数组
- ‘setting‘=>array(),//设置变量数组
- ‘member‘=>array(),//用户信息数组
- ‘group‘=>array(),//用户组数组
- ‘cookie‘=>array(),//cookie数组
- ‘style‘=>array(),//风格数组
- ‘cache‘=>array(),//缓存列表数组
- ‘session‘=>array(),//session变量数组
- ‘lang‘=>array(),//语言包数组
- ‘my_app‘=>array(),//我的应用数组
- ‘my_userapp‘=>array(),//用户应用数组
- ‘fid‘=>0,//版块id
- ‘tid‘=>0,//帖子id
- ‘forum‘=>array(),//论坛版块数组
- ‘thread‘=>array(),//论坛相关帖子数组
- ‘rssauth‘=>‘‘,//RSS订阅认证
- ‘home‘=>array(),//home功能相关数组
- ‘space‘=>array(),//space功能相关数组
- ‘block‘=>array(),//块信息数组
- ‘article‘=>array(),//文章相关
- ‘action‘=>array(
- ‘action‘=>APPTYPEID,
- ‘fid‘=>0,//版块id
- ‘tid‘=>0,//帖子id
- ),
- ‘mobile‘=>‘‘,//手机信息
- );
- $_G[‘PHP_SELF‘]=htmlspecialchars($this->_get_script_url());//将当前脚本地址写入$_G超级变量中;结果:"/discuz/forum.php"
- $_G[‘basescript‘]=CURSCRIPT;//当前不带扩展名的php脚本,如:"forum"
- $_G[‘basefilename‘]=basename($_G[‘PHP_SELF‘]);//显示带有文件扩展名的php文件名称,如:"forum.php"
- $sitepath=substr($_G[‘PHP_SELF‘],0,strrpos($_G[‘PHP_SELF‘],‘/‘));//如:"/discuz"
- if(defined(‘IN_API‘)){
- $sitepath=preg_replace("/\/api\/?.*?$/i",‘‘,$sitepath);
- }elseif(defined(‘IN_ARCHIVER‘)){
- $sitepath=preg_replace("/\/archiver/i",‘‘,$sitepath);
- }
- $_G[‘siteurl‘]=htmlspecialchars(‘http://‘.$_SERVER[‘HTTP_HOST‘].$sitepath.‘/‘);//网站地址
- $url=parse_url($_G[‘siteurl‘]);
- $_G[‘siteroot‘]=isset($url[‘path‘])?$url[‘path‘]:‘‘;//网站根目录,如:"/discuz"
- $_G[‘siteport‘]=empty($_SERVER[‘SERVER_PORT‘])||$_SERVER[‘SERVER_PORT‘]==‘80‘?‘‘:‘:‘.$_SERVER[‘SERVER_PORT‘];//端口
- if(defined(‘SUB_DIR‘)){//二级目录设置情况
- $_G[‘siteurl‘]=str_replace(SUB_DIR,‘/‘,$_G[‘siteurl‘]);
- $_G[‘siteroot‘]=str_replace(SUB_DIR,‘/‘,$_G[‘siteroot‘]);
- }
- $this->var=&$_G;//$_G变量的引用赋值给$var,以后对$_G变量或$var变量的修改会直接影响到对方
- }
- /*
- *1、返回PHP_SELF当前脚本文件
- */
- function_get_script_url(){
- if($this->var[‘PHP_SELF‘]===null){
- $scriptName=basename($_SERVER[‘SCRIPT_FILENAME‘]);
- if(basename($_SERVER[‘SCRIPT_NAME‘])===$scriptName){
- $this->var[‘PHP_SELF‘]=$_SERVER[‘SCRIPT_NAME‘];
- }elseif(basename($_SERVER[‘PHP_SELF‘])===$scriptName){
- $this->var[‘PHP_SELF‘]=$_SERVER[‘PHP_SELF‘];
- }elseif(isset($_SERVER[‘ORIG_SCRIPT_NAME‘])&&basename($_SERVER[‘ORIG_SCRIPT_NAME‘])===$scriptName){
- $this->var[‘PHP_SELF‘]=$_SERVER[‘ORIG_SCRIPT_NAME‘];
- }elseif(($pos=strpos($_SERVER[‘PHP_SELF‘],‘/‘.$scriptName))!==false){
- $this->var[‘PHP_SELF‘]=substr($_SERVER[‘SCRIPT_NAME‘],0,$pos).‘/‘.$scriptName;
- }elseif(isset($_SERVER[‘DOCUMENT_ROOT‘])&&strpos($_SERVER[‘SCRIPT_FILENAME‘],$_SERVER[‘DOCUMENT_ROOT‘])===0){
- $this->var[‘PHP_SELF‘]=str_replace(‘\\‘,‘/‘,str_replace($_SERVER[‘DOCUMENT_ROOT‘],‘‘,$_SERVER[‘SCRIPT_FILENAME‘]));
- }else{
- system_error(‘request_tainting‘);
- }
- }
- return$this->var[‘PHP_SELF‘];
- }
- /*
- *1、合并$_POST和$_GET,然后将$_POST和$_GET的值都赋予gp变量中,方便使用
- *2、禁止对全局变量注入
- *3、slashes处理
- *4、cookie处理:去掉cookie前缀
- */
- function_init_input(){
- if(isset($_GET[‘GLOBALS‘])||isset($_POST[‘GLOBALS‘])||isset($_COOKIE[‘GLOBALS‘])||isset($_FILES[‘GLOBALS‘])){
- system_error(‘request_tainting‘);//...请求中...
- }
- if(!MAGIC_QUOTES_GPC){//魔术函数是否开启:仅仅对$_GET、$_POST、$_COOKIE起作用;主要用于在讲数据入库前做一些安全性的转义
- $_GET=daddslashes($_GET);//对$_GET数据进行转义
- $_POST=daddslashes($_POST);//对$_POST数据进行转义
- $_COOKIE=daddslashes($_COOKIE);//对$_COOKIE数据进行转义
- $_FILES=daddslashes($_FILES);//对$_FILES数据进行转义
- }
- /*
- *1、如果cookie的键值等于定义的键值,那么截取cookie的前缀cookiepre
- */
- $prelength=strlen($this->config[‘cookie‘][‘cookiepre‘]);
- foreach($_COOKIEas$key=>$val){
- if(substr($key,0,$prelength)==$this->config[‘cookie‘][‘cookiepre‘]){
- $this->var[‘cookie‘][substr($key,$prelength)]=$val;//cookie赋值
- }
- }
- /*
- *1、合并$_POST和$_GET,然后将$_POST和$_GET的值都赋予gp变量中,方便使用
- */
- if($_SERVER[‘REQUEST_METHOD‘]==‘POST‘&&!empty($_POST)){
- $_GET=array_merge($_GET,$_POST);
- }
- //diy
- if(isset($_GET[‘diy‘])){
- $_GET[‘diy‘]=empty($_GET[‘diy‘])?‘‘:$_GET[‘diy‘];
- }
- foreach($_GETas$k=>$v){
- $this->var[‘gp_‘.$k]=$v;//将$_POST和$_GET的值都赋予gp变量中,方便使用
- }
- //获取$mod变量,如:/?mod=xxx,那么$this->var[‘mod‘]=xxx;
- $this->var[‘mod‘]=empty($this->var[‘gp_mod‘])?‘‘:htmlspecialchars($this->var[‘gp_mod‘]);
- //是否需要ajax方式
- $this->var[‘inajax‘]=empty($this->var[‘gp_inajax‘])?0:(empty($this->var[‘config‘][‘output‘][‘ajaxvalidate‘])?1:($_SERVER[‘REQUEST_METHOD‘]==‘GET‘&&$_SERVER[‘HTTP_X_REQUESTED_WITH‘]==‘XMLHttpRequest‘||$_SERVER[‘REQUEST_METHOD‘]==‘POST‘?1:0));
- //页面获取,最小为1
- $this->var[‘page‘]&