DISCUZ 之论坛首页加载过程,FORUM相关(转帖)

可能有理解不透彻的地方,欢迎回帖拍砖,会多加改进php

一、加载class_core.php可查看全局数据初始化的另一个笔记css

二、功能模块中哦跟你的mod对应了source/forum中指定的文件。
缓存模块根据当前所处的功能模块,加载必需的缓存内容,默认的缓存内容通常会在操做完指定模块以后存放在用二进制的形式序列化后存放在数据库表中
//BBS相关的功能模块   html

[php]  view plain  copy
 
  1. $modarray = array('ajax','announcement','attachment','forumdisplay',     
  2.     'group','image','index','medal','misc','modcp','notice','post','redirect',     
  3.     'relatekw','relatethread','rss','topicadmin','trade','viewthread','tag','collection','guide'  
  4. );     

  
//缓存相关的数据模块   

[php]  view plain  copy
 
  1. $modcachelist = array(     
  2.     'index'     => array('announcements', 'onlinelist', 'forumlinks',     
  3.             'heats', 'historyposts', 'onlinerecord', 'userstats', 'diytemplatenameforum'),     
  4.     'forumdisplay'  => array('smilies', 'announcements_forum', 'globalstick', 'forums',     
  5.             'onlinelist', 'forumstick', 'threadtable_info', 'threadtableids', 'stamps', 'diytemplatenameforum'),     
  6.     'viewthread'    => array('smilies', 'smileytypes', 'forums', 'usergroups',     
  7.             'stamps', 'bbcodes', 'smilies', 'custominfo', 'groupicon', 'stamps',     
  8.             'threadtableids', 'threadtable_info', 'posttable_info', 'diytemplatenameforum'),     
  9.     'redirect'  => array('threadtableids', 'threadtable_info', 'posttable_info'),     
  10.     'post'      => array('bbcodes_display', 'bbcodes', 'smileycodes', 'smilies', 'smileytypes',     
  11.             'domainwhitelist', 'albumcategory'),     
  12.     'space'     => array('fields_required', 'fields_optional', 'custominfo'),     
  13.     'group'     => array('grouptype', 'diytemplatenamegroup'),     
  14. );  


//对于不在modarray中的值,视为非法内容,直接替换成index。   
//C::app()->var['mod']的值在加载class_core.php时初始化函数_init_input()中已经赋值,起始就是URL中的一个参数值   前端

[php]  view plain  copy
 
  1. $mod = !in_array(C::app()->var['mod'], $modarray) ? 'index' : C::app()->var['mod'];  


其中C是core的一个子类java

[php]  view plain  copy
 
  1. C::app()->cachelist = $cachelist;     
  2. C::app()->init();  


    若是说class_core.php是执行初始化的工做,或者说声明必要的内容,那么这里的C::app()->init()就是把基本上须要的内容都获取到,例如数据库链接,后台设置的内容,用户信息,session信息等等。具体往下看。mysql

[php]  view plain  copy
 
  1. public function init() {     
  2.         if(!$this->initated) {     
  3.             $this->_init_db();     
  4.             $this->_init_setting();     
  5.             $this->_init_user();     
  6.             $this->_init_session();     
  7.             $this->_init_mobile();     
  8.             $this->_init_cron();     
  9.             $this->_init_misc();     
  10.         }     
  11.         $this->initated = true;     
  12. }  


    同样,从各个函数中的名称能够稍微理解每一个都会进行些什么相关的内容,这一点在加载class_core.php时就遇到了,core类的构造函数的操做方式就跟这个非常相似。

三、该函数的主要任务就是链接数据库,重点所链接的时候涉及到不一样数据库版本对字符集的设置问题android

[php] view plain copyweb

 
  1. private function _init_db() {     
  2.         if($this->init_db) {     
  3.             $driver = 'db_driver_mysql';     
  4.             if(count(getglobal('config/db/slave'))) {     
  5.                 $driver = 'db_driver_mysql_slave';     
  6.             }     
  7.             DB::init($driver, $this->config['db']);     
  8.         }     
  9. }  

     DB类在加载class_core.php的最后继承了class DB extends discuz_database {}类discuz_database,稍微查看下该文件就能够看出,对于数据库相关的操做如获取数据库配置信息,链接数据库,查询、删除、更新数据库表等都从新封装过。    init_db变量在声明该类的时候就初始化默认为true,而db_driver_mysql中基本上封装了须要用到的数据库操做,而discuz_database就能够看成是一个代理,而正真完成操做的则为在更为底层的db_driver_mysql.    至于db_driver_mysql_slave暂时尚未怎么留意到,后续补充ajax

[php]  view plain  copy
 
  1. public static function init($driver, $config) {     
  2.         self::$driver = $driver;     
  3.         self::$db = new $driver;     
  4.         self::$db->set_config($config);     
  5.         self::$db->connect();     
  6. }  

    如上所说,这里的$driver=db_driver_mysql,其中set_config 就是为了获得数据的配置信息,HOST、名、用户、密码等包括数据库前缀四、redis

[php]  view plain  copy
 
  1. private function _init_setting() {     
  2.         if($this->init_setting) {     
  3.             if(empty($this->var['setting'])) {     
  4.                 $this->cachelist[] = 'setting';     
  5.             }     
  6.     
  7.             if(empty($this->var['style'])) {     
  8.                 $this->cachelist[] = 'style_default';     
  9.             }     
  10.     
  11.             if(!isset($this->var['cache']['cronnextrun'])) {     
  12.                 $this->cachelist[] = 'cronnextrun';     
  13.             }     
  14.         }     
  15.     
  16.         !empty($this->cachelist) && loadcache($this->cachelist);     
  17.     
  18.         if(!is_array($this->var['setting'])) {     
  19.             $this->var['setting'] = array();     
  20.         }     
  21.     
  22. }  



    默认状况下,$this->cachelist[]数组中会加入setting,style_default,cronnextrun三个元素,重点在loadcache()函数


    对于loadcache()函数,其中重点则在于

[php]  view plain  copy
 
  1. $cachedata = C::t('common_syscache')->fetch_all($caches);  


    文件table_common_syscache.php中的fetch_all函数。在看fetch_all()函数以前,留意下类table_common_syscache的构造函数

[php]  view plain  copy
 
  1. public function __construct() {     
  2.     
  3.         $this->_table = 'common_syscache';     
  4.         $this->_pk    = 'cname';     
  5.         $this->_pre_cache_key = '';     
  6.         $this->_isfilecache = getglobal('config/cache/type') == 'file';     
  7.         $this->_allowmem = memory('check');     
  8.     
  9.         parent::__construct();     
  10.     }  

    这里除了获取些基本信息以外,还会检查系统如今默认使用的缓存方式(在配置文件config_global.php中能够设置,默认使用了SQL的数据库存放方式,另外还有一种文件缓存方式,下面根据默认的说下数据库缓存。)
留心发现还有一句

[php]  view plain  copy
 
  1. $this->_allowmem = memory('check');  

    这个就是PHP中用到的内存缓存的检查工做了,这种类型的缓存方式有redis,memcache,apc,xcache,eaccelerator,wincache,要使用哪种方式,能够了解下PHP的内存缓存机制,不一样的缓存方式对于不一样的站点有不同的效果,跟服务器、访问量都有些关系。
    内存缓存是要服务器支持的状况下,在经过配置文件进行配置才可使用。不一样于下面将会继续说道的discuz中用到的文件缓存和数据库缓存,虽然同为缓存,可是使用的方式彻底不同。


    接下来看fetch_all函数的内容

[php]  view plain  copy
 
  1. $cachenames = is_array($cachenames) ? $cachenames : array($cachenames);  

    discuz中不少地方均可以发现相似的写法,目的就是为了更直接的处理相似功能的操做,例如dhtmlspecialchars()函数,其实就是封装了PHP中默认的htmlspecialchars()函数,除了根据PHP版本作不一样的编码工做,对有多是数组形式的字符串数组作编码,这样也就为何上面这句比较常见的缘由了。

[php]  view plain  copy
 
  1. if($this->_allowmem) {//在构造函数中检查是否支持内存缓存,是的话就将     
  2.             $data = memory('get', $cachenames);     
  3.             $newarray = $data !== false ? array_diff($cachenames, array_keys($data)) : $cachenames;     
  4.             if(empty($newarray)) {     
  5.                 return $data;     
  6.             } else {     
  7.                 $cachenames = $newarray;     
  8.             }     
  9.         }  

    在构造函数中检测的结果就在这里用上了,当发现系统支持内存缓存的时候,就根据当前使用的内存缓存方式去系统内存中获取缓存数据。抛开封装相关的类函数不说,直接看source/class/memory/memory_driver_memcache.php当前目录的这些脚本,就是根据不一样的内存缓存方式执行不一样的操做,基本就涵盖了设置set,get,delete等操做。


[php]  view plain  copy
 
  1. if($this->_isfilecache) {     
  2.             $lostcaches = array();     
  3.             foreach($cachenames as $cachename) {     
  4.                 if(!@include_once(DISCUZ_ROOT.'./data/cache/cache_'.$cachename.'.php')) {     
  5.                     $lostcaches[] = $cachename;     
  6.                 } elseif($this->_allowmem) {     
  7.                     memory('set', $cachename, $data[$cachename]);     
  8.                 }     
  9.             }     
  10.             if(!$lostcaches) {     
  11.                 return $data;     
  12.             }     
  13.             $cachenames = $lostcaches;     
  14.             unset($lostcaches);     
  15.         }  

    若使用的是文件缓存方式,拿理所固然的所去缓存文件中获取数据了。缓存的数据根据缓存名称放在了data/cache目录下。留心发现还能找到在支持内存缓存的时候,代码会有个断定并加入缓存的操做。

[php]  view plain  copy
 
  1. memory('set', $cachename, $data[$cachename]);  

 

[php]  view plain  copy
 
  1. $query = DB::query('SELECT * FROM '.DB::table($this->_table).' WHERE '.DB::field('cname', $cachenames));     
  2.         while($syscache = DB::fetch($query)) {     
  3.             $data[$syscache['cname']] = $syscache['ctype'] ? unserialize($syscache['data']) : $syscache['data'];     
  4.             $this->_allowmem && (memory('set', $syscache['cname'], $data[$syscache['cname']]));     
  5.             if($this->_isfilecache) {     
  6.                 $cachedata = '$data[\''.$syscache['cname'].'\'] = '.var_export($data[$syscache['cname']], true).";\n\n";     
  7.                 if(($fp = @fopen(DISCUZ_ROOT.'./data/cache/cache_'.$syscache['cname'].'.php', 'wb'))) {     
  8.                     fwrite($fp, "<?php\n//Discuz! cache file, DO NOT modify me!\n//Identify: ".md5($syscache['cname'].$cachedata.getglobal('config/security/authkey'))."\n\n$cachedata?>");     
  9.                     fclose($fp);     
  10.                 }     
  11.             }     
  12.         }  

   这段就是默认的是使用了数据库缓存所获得的缓存数据了,缓存数据被存放在表pre_common_syscache表中。通常状况下都是将经常使用的、不变的数据都会放在里面,例如后台的设置信息基本上都会有,存放的方式是有对应关系的数组以二进制的形式存放。


    经过以上内存缓存、文件缓存、和数据库缓存,这块的缓存工做就基本上结束了,固然这里指的是读取缓存的工做,至于存储缓存的工做请看以下function_core.php文件中的savecache()函数:

[php]  view plain  copy
 
  1. function savecache($cachename, $data) {     
  2.     C::t('common_syscache')->insert($cachename, $data);     
  3. }  


    使用到了同个类table_common_syscache中的insert函数

[php]  view plain  copy
 
  1. public function insert($cachename, $data) {     
  2.     
  3.         parent::insert(array(     
  4.             'cname' => $cachename,     
  5.             'ctype' => is_array($data) ? 1 : 0,     
  6.             'dateline' => TIMESTAMP,     
  7.             'data' => is_array($data) ? serialize($data) : $data,     
  8.         ), false, true);     
  9.     
  10.         if($this->_allowmem && memory('get', $cachename) !== false) {     
  11.             memory('set', $cachename, $data);     
  12.         }     
  13.         $this->_isfilecache && @unlink(DISCUZ_ROOT.'./data/cache/cache_'.$cachename.'.php');     
  14.     }  

    函数理所固然的包括了数据库存储,内存缓存设置,将旧的缓存文件删除。

[php]  view plain  copy
 
  1. $cachedata = C::t('common_syscache')->fetch_all($caches);     
  2.         foreach($cachedata as $cname => $data) {     
  3.             if($cname == 'setting') {     
  4.                 $_G['setting'] = $data;     
  5.             } elseif($cname == 'usergroup_'.$_G['groupid']) {     
  6.                 $_G['cache'][$cname] = $_G['group'] = $data;     
  7.             } elseif($cname == 'style_default') {     
  8.                 $_G['cache'][$cname] = $_G['style'] = $data;     
  9.             } elseif($cname == 'grouplevels') {     
  10.                 $_G['grouplevels'] = $data;     
  11.             } else {     
  12.                 $_G['cache'][$cname] = $data;     
  13.             }     
  14.         }  

   缓存获取的操做作完以后,DISCUZ系统习惯性的将这些数据存放进了$_G这个全局变量中了。

五、函数_init_user(),从名字能够大概知道其主要执行的是用户相关的操做。

[php]  view plain  copy
 
  1. if($auth = getglobal('auth', 'cookie')) {     
  2.                 $auth = daddslashes(explode("\t", authcode($auth, 'DECODE')));     
  3.             }     
  4.             list($discuz_pw, $discuz_uid) = empty($auth) || count($auth) < 2 ? array('', '') : $auth;     
  5.     
  6.             if($discuz_uid) {     
  7.                 $user = getuserbyuid($discuz_uid, 1);     
  8. }  

      这一步是为了识别、并经过函数getuserbyuid()获取用户信息的,从名为auth的cookie中获取内容,同时经过具有加密解密功能的authcode()函数,对cookie的字符串auth进行解密获得用户的uid和密码。仔细观察客户端中的cookie值,auth是包含前缀名的,没错,往前面看的话别忘了class_core类中的init_input函数,以前讲过,对于discuz的cookie都会默认加上前缀,在获取到客户端数据的时候,就已经在init_input函数中去掉了前缀,这样获得的名称就更有识别性。
  

[php]  view plain  copy
 
  1.     
  2. if(!empty($user) && $user['password'] == $discuz_pw) {     
  3.                 if(isset($user['_inarchive'])) {     
  4.                     C::t('common_member_archive')->move_to_master($discuz_uid);     
  5.                 }     
  6.                 $this->var['member'] = $user;     
  7.             } else {     
  8.                 $user = array();     
  9.                 $this->_init_guest();     
  10.             }     
  11.     
  12.             if($user && $user['groupexpiry'] > 0 && $user['groupexpiry'] < TIMESTAMP && (getgpc('mod') != 'spacecp' || CURSCRIPT != 'home')) {     
  13.                 dheader('location: home.php?mod=spacecp&ac=usergroup&do=expiry');     
  14.             }     
  15.     
  16.             $this->cachelist[] = 'usergroup_'.$this->var['member']['groupid'];     
  17.             if($user && $user['adminid'] > 0 && $user['groupid'] != $user['adminid']) {     
  18.                 $this->cachelist[] = 'admingroup_'.$this->var['member']['adminid'];     
  19.  }  
  20. if(empty($this->var['cookie']['lastvisit'])) {     
  21.             $this->var['member']['lastvisit'] = TIMESTAMP - 3600;     
  22.             dsetcookie('lastvisit', TIMESTAMP - 3600, 86400 * 30);     
  23.         } else {     
  24.             $this->var['member']['lastvisit'] = $this->var['cookie']['lastvisit'];     
  25.         }     
  26.     
  27.         setglobal('uid', getglobal('uid', 'member'));     
  28.         setglobal('username', getglobal('username', 'member'));     
  29.         setglobal('adminid', getglobal('adminid', 'member'));     
  30.         setglobal('groupid', getglobal('groupid', 'member'));     
  31.     
  32.         !empty($this->cachelist) && loadcache($this->cachelist);  

    剩下的这些基本上都是为了从新设置用户信息相关的,而这些信息主要为了设置几个在全局变量$_G中的一级元素uid,username,adminid,groupid,和member下的二级元素的值。
同时根据当前用户是否为游客则执行游客信息的初始化工做_init_guest(),其实这个过程也就是将几个默认的数据放入$_G['member']中;
若是是已登陆用户,首先判断用户所在用户组groupexpiry是否已通过期,是的话则跳转到我的设置的用户组页面;
获得用户所在用户组关系后,在以usergroup为前缀的缓存数据中获取当前用户组的缓存信息,获取工做就交给接下来会执行的loadcache函数了。

六、函数init_session(),操做些session相关的东西,仔细研究DISCUZ的SESSION机制,会发现其跟PHP自带的SESSION机制所不同的,这里所谓的SESSION基本上是DISCUZ本身从新定制的机制,至于为何要独立使用本身的sessin机制而抛弃PHP自带的,具体缘由就不是很清楚,可是查看DISCUZ安装后获得的数据库表结构,能够发现pre_common_session使用的数据库引擎方式竟然是有别于其余myisam的memory,也就是所谓的内存表,该类型的表数据是放在内存中的,默认使用了hash索引,访问起来会很是快,这或许就是使用本身的一套机制的缘由吧。

 

[php]  view plain  copy
 
  1. private function _init_session() {     
  2.     
  3.         $sessionclose = !empty($this->var['setting']['sessionclose']);     
  4.         $this->session = $sessionclose ? new discuz_session_close() : new discuz_session();     
  5.     
  6.         if($this->init_session)  {     
  7.             $this->session->init($this->var['cookie']['sid'], $this->var['clientip'], $this->var['uid']);     
  8.             $this->var['sid'] = $this->session->sid;     
  9.             $this->var['session'] = $this->session->var;     
  10.     
  11.             if(!empty($this->var['sid']) && $this->var['sid'] != $this->var['cookie']['sid']) {     
  12.                 dsetcookie('sid', $this->var['sid'], 86400);     
  13.             }     
  14.     
  15.             if($this->session->isnew) {     
  16.                 if(ipbanned($this->var['clientip'])) {     
  17.                     $this->session->set('groupid', 6);     
  18.                 }     
  19.             }     
  20.     
  21.             if($this->session->get('groupid') == 6) {     
  22.                 $this->var['member']['groupid'] = 6;     
  23.                 sysmessage('user_banned');     
  24.             }     
  25.     
  26.             if($this->var['uid'] && !$sessionclose && ($this->session->isnew || ($this->session->get('lastactivity') + 600) < TIMESTAMP)) {     
  27.                 $this->session->set('lastactivity', TIMESTAMP);     
  28.                 if($this->session->isnew) {     
  29.                     C::t('common_member_status')->update($this->var['uid'], array('lastip' => $this->var['clientip'], 'lastvisit' => TIMESTAMP));     
  30.                 }     
  31.             }     
  32.     
  33.         }     
  34.     }  


     接下来讲的是当$sessionclose==false的状况下的内容。关键操做也在类discuz_session中,如上代码中第六行。

[php]  view plain  copy
 
  1. public function init($sid, $ip, $uid) {     
  2.         $this->old = array('sid' =>  $sid, 'ip' =>  $ip, 'uid' =>  $uid);     
  3.         $session = array();     
  4.         if($sid) {     
  5.             $session = $this->table->fetch($sid, $ip, $uid);     
  6.         }     
  7.     
  8.         if(empty($session) || $session['uid'] != $uid) {     
  9.             $session = $this->create($ip, $uid);     
  10.         }     
  11.     
  12.         $this->var = $session;     
  13.         $this->sid = $session['sid'];     
  14.     }  

    会发现cookie在discuz中发挥的重要做用了吧,sid就是保存在客户端中的该用户当前浏览器对应的服务器中的session的ID,除了session的id,这里所须要的参数还包括了用户的UID,客户端IP,大部分的重要信息都须要通过cookie的合做才可以顺利的进行,这里就出现疑问,在客户端禁止cookie的状况下discuz的运行又会是怎样的?后续须要了解。
    下面的是table_common_session.php中的fetch函数

[php]  view plain  copy
 
  1. public function fetch($sid, $ip = false, $uid = false) {     
  2.         if(empty($sid)) {     
  3.             return array();     
  4.         }     
  5.         $this->checkpk();     
  6.         $session = parent::fetch($sid);     
  7.         if($session && $ip !== false && $ip != "{$session['ip1']}.{$session['ip2']}.{$session['ip3']}.{$session['ip4']}") {     
  8.             $session = array();     
  9.         }     
  10.         if($session && $uid !== false && $uid != $session['uid']) {     
  11.             $session = array();     
  12.         }     
  13.         return $session;     
  14.     }  


    会调用其父类discuz_table中的fetch()函数

[php]  view plain  copy
 
  1. public function fetch($id, $force_from_db = false){     
  2.         $data = array();     
  3.         if(!empty($id)) {     
  4.             if($force_from_db || ($data = $this->fetch_cache($id)) === false) {     
  5.                 $data = DB::fetch_first('SELECT * FROM '.DB::table($this->_table).' WHERE '.DB::field($this->_pk, $id));     
  6.                 if(!empty($data)) $this->store_cache($id, $data);     
  7.             }     
  8.         }     
  9.         return $data;     
  10.     }  


    数据库表类的父类discuz_table的两个基本函数fetch_cache()和store_cache()在这里的做用就是,在获取session的过程当中,若是在内存缓存中可以获得session的内容,就会跳过在数据库表格common_session中查找内容,若是没有的话就进行查询,这里调试的结果是在没有支持内存缓存的环境下,会到数据库表格中进行查找并获取数据,获取到的数据会尝试将其保存在内存缓存中,也就是store_cache()的工做了。
执行完毕回到刚才类table_common_session中:
其一会在取得session内容的状况下,判断客户端IP跟获取到的session中的ip是否相同,不一样的话就将session置空,由于当前用户所使用的客户端IP已经修改。
其二也会取得session内容的状况下,判断客户端相同ip,可是session中的uid已经不一样,也就是客户端浏览器使用了另一个用户登陆,此时对应的session也须要重置。
到这里session的获取工做就基本上完成,而这里的获取session也就是获取了用户相关的客户端信息,以下面调试的数据:

[php]  view plain  copy
 
  1. array(14) (     
  2.   [sid] => (string) cnksCz     
  3.   [ip1] => (string) 127     
  4.   [ip2] => (string) 0     
  5.   [ip3] => (string) 0     
  6.   [ip4] => (string) 1     
  7.   [uid] => (string) 1     
  8.   [username] => (string) admin     
  9.   [groupid] => (string) 1     
  10.   [invisible] => (string) 0     
  11.   [action] => (string) 2     
  12.   [lastactivity] => (string) 1378193039     
  13.   [lastolupdate] => (string) 1378193039     
  14.   [fid] => (string) 0     
  15.   [tid] => (string) 0     
  16. )  

   上面说到了可能获取的session为空的状况,往回看在init()函数中会有个create()函数,其实就是从新生成一个新的session数组,其中sid的值是经过random(6)随机生成的,其余都是根据当前状况赋予内容。再将相关值赋值到discuz_session对象的变量中,供init_session()函数完成接下来的工做。
    剩下来的会判断当前的sid跟客户端的sid是否相同,否的话就从新设置dsetcookie()客户端的sid的cookie值;对于从新create出来的session,会判断用户访问的ip是否在被禁止访问的ip名单中,若是是的话会将用户置为groupid为6即“用户IP被禁止”的系统用户组中,并抛出提醒;而没有被禁止的用户能够继续执行后面的内容,后面的也就剩下当当前用户所在登陆状态下,且超过了600秒的有效期以后,同时也就是如今也处于活动状态,就从新更新用户在session的最后活动时间以及用户状态表common_member_status中的状态信息。    

七、函数_init_mobile()
    判断在后台是否容许使用手机页面的访问,是的话就初始化各类跟手机页面访问所须要的数据,不然就return false,没有什么特别的操做,其中有个颇有用的函数,在其余项目中能够考虑使用,就是检测当前客户端使用的是否为手机客户端。

[php]  view plain  copy
 
  1. function checkmobile() {     
  2.     global $_G;     
  3.     $mobile = array();     
  4.     static $mobilebrowser_list =array('iphone', 'android', 'phone', 'mobile', 'wap', 'netfront', 'java', 'opera mobi', 'opera mini',     
  5.                 'ucweb', 'windows ce', 'symbian', 'series', 'webos', 'sony', 'blackberry', 'dopod', 'nokia', 'samsung',     
  6.                 'palmsource', 'xda', 'pieplus', 'meizu', 'midp', 'cldc', 'motorola', 'foma', 'docomo', 'up.browser',     
  7.                 'up.link', 'blazer', 'helio', 'hosin', 'huawei', 'novarra', 'coolpad', 'webos', 'techfaith', 'palmsource',     
  8.                 'alcatel', 'amoi', 'ktouch', 'nexian', 'ericsson', 'philips', 'sagem', 'wellcom', 'bunjalloo', 'maui', 'smartphone',     
  9.                 'iemobile', 'spice', 'bird', 'zte-', 'longcos', 'pantech', 'gionee', 'portalmmm', 'jig browser', 'hiptop',     
  10.                 'benq', 'haier', '^lct', '320x320', '240x320', '176x220');     
  11.     $pad_list = array('pad', 'gt-p1000');     
  12.     
  13.     $useragent = strtolower($_SERVER['HTTP_USER_AGENT']);     
  14.     
  15.     if(dstrpos($useragent, $pad_list)) {     
  16.         return false;     
  17.     }     
  18.     if(($v = dstrpos($useragent, $mobilebrowser_list, true))) {     
  19.         $_G['mobile'] = $v;     
  20.         return true;     
  21.     }     
  22.     $brower = array('mozilla', 'chrome', 'safari', 'opera', 'm3gate', 'winwap', 'openwave', 'myop');     
  23.     if(dstrpos($useragent, $brower)) return false;     
  24.     
  25.     $_G['mobile'] = 'unknown';     
  26.     if($_GET['mobile'] === 'yes') {     
  27.         return true;     
  28.     } else {     
  29.         return false;     
  30.     }     
  31. }  

    函数_init_cron()执行的是discuz系统中的计划任务; 函数_init_misc()执行的是discuz系统除了上述以外的其余杂七杂八的初始化工做,无特殊之处;而前面的计划任务或许能够深究。
到这里论坛的初始化工做就基本上完成了,至于每一个地方有什么用,都会很详尽地将须要的数据提供出来,从这个过程也能够看出DISCUZ的人在这么多年的积累仍是作到很是之不错的,其中也有不少值得咱们去学习的。

例如在使用某个变量的时候,能够发现它都会在该类的最前端初始化该变量;在服务端不须要使用到的数据,DISCUZ会直接过滤掉而不容许出现任何可能形成不安全的影响;其整个discuz的框架也分的很清楚,虽然这里没有说到,多了解下能够看到整个系统的执行过程按部就班、各个功能块都分得很清楚,这里说到的数据初始化、缓存的定制、插件的自定义工做以及模板上所带有的MVC结构等。

相关文章
相关标签/搜索