打開admin.phpphp
define('IN_ADMINCP', TRUE);html
//定義常量IN_ADMINCP爲true 這樣在後面的每一個頁面都會判斷web
if(!defined('IN_DISCUZ') || !defined('IN_ADMINCP')) {
exit('Access Denied');
}api
//防止外面直接訪問後臺文件,必須經過admin.php包含才能夠訪問其餘文件,IN_DISCUZ在/sorce/class/class_core.php裏定義的常量,後面幾行立刻包含該文件數組
define('NOROBOT', TRUE);cookie
//定義常量NOROBOT爲true,用於阻止搜索引擎爬蟲抓取。session
define('ADMINSCRIPT', basename(__FILE__));//admin.phpapp
//__FILE__是獲取文件磁盤位置詳細路徑,好比:D:\DedeAMPZ\web2013\discuz_video\upload\admin.phpide
//basename(__FILE__)就是取文件名 也就是admin.php函數
define('CURSCRIPT', 'admin');
//定義常量CURSCRIPT爲admin,當前腳本爲admin
define('HOOKTYPE', 'hookscript');
//定義常量HOOKTYPE 爲 hookscript
define('APPTYPEID', 0);
//定義APPTYPEID 爲 0
require './source/class/class_core.php';
包含核心類class_core.php
程序進入class_core.php內
error_reporting(E_ALL);
//定義錯誤報告爲E_ALL
define('IN_DISCUZ', true);
//定義常量IN_DISCUZ爲true 後續判讀,防止外界直接訪問內部頁面
define('DISCUZ_ROOT', substr(dirname(__FILE__), 0, -12));
//定義DISCUZ_ROOT爲DISCUZ的根目錄也就是upload目錄的磁盤位置,這個常量後續會很經常使用到
define('DISCUZ_CORE_DEBUG', false);
//定義調試模式爲 false後續能夠修改成true進行調試
define('DISCUZ_TABLE_EXTENDABLE', TRUE);
//定義常量'DISCUZ_TABLE_EXTENDABLE' 爲true
set_exception_handler(array('core', 'handleException'));
//PHP自帶函數 使用 core::handleException 來執行異常處理能夠是單個函數名爲參數,也能夠是類和函數組成的數組
if(DISCUZ_CORE_DEBUG) {
set_error_handler(array('core', 'handleError'));//設置錯誤處理函數 core::handleError 來執行
register_shutdown_function(array('core', 'handleShutdown'));//致命錯誤處理函數 core::handleShutdown 來執行
}
//若是是調試模式的話設置錯誤處理函數爲core::handleError,設置致命錯誤處理函數爲core::handleShutdown
if(function_exists('spl_autoload_register')) {
spl_autoload_register(array('core', 'autoload'));
} else {
function __autoload($class) {
return core::autoload($class);
}
}
//自動加載類,執行 如下autoload函數 PHP5以後若是試圖調用沒有加載的類就會自動調用__autoload()函數或者執行spl_autoload_register()指定的函數
//直接調用類時會先調用core::autoload($class)函數,在這個函數裏會包含該類文件
C::creatapp();
//執行C::createapp()函數,雙冒號是調用類的靜態函數。DISCUZ裏大多都用的是靜態函數
在類名的最下方有C的定義
class C extends core {}
class DB extends discuz_database {}
類名C是繼承於core的,執行C::createapp()就是執行core::createapp()
再看core::createapp()函數以下:
public static function creatapp() {
if(!is_object(self::$_app)) {
//discuz_application主要定義了mem session misic mobile setting等數組
//在這裏直接調用discuz_application類,會觸發core::autoload('discuz_application')執行,由於spl_autoload_register()函數設置了
self::$_app = discuz_application::instance();//因爲執行了spl_autoload_register自動加載類
//instance執行了$object = new self();這樣就執行了__construct函數
}
return self::$_app;
}
該函數直接返回core::$_app , core::$_app 開始爲空,因此調用discuz_application::instance();
因爲上面設置了類自動加載,因此調用discuz_application的時候,會先調用
core::autoload()函數,
函數執行到 core::autoload()裏,代碼以下:
//自動加載類
public static function autoload($class) {
$class = strtolower($class);//變爲小寫
if(strpos($class, '_') !== false) {
list($folder) = explode('_', $class);
$file = 'class/'.$folder.'/'.substr($class, strlen($folder) + 1);
} else {
$file = 'class/'.$class;
}
try {
self::import($file);
return true;
} catch (Exception $exc) {
$trace = $exc->getTrace();
foreach ($trace as $log) {
if(empty($log['class']) && $log['function'] == 'class_exists') {
return false;
}
}
discuz_error::exception_error($exc);
}
}
//此時傳遞給autoload的變量$class是discuz_application,因爲文件名中含有_,因此$file是class/discuz/discuz_application.php,若是沒有_的類,則在class/類名.php,而後執行
self::import($file);
函數進入core::import()內代碼以下:
public static function import($name, $folder = '', $force = true) {
$key = $folder.$name;
if(!isset(self::$_imports[$key])) {
$path = DISCUZ_ROOT.'/source/'.$folder;
if(strpos($name, '/') !== false) {
$pre = basename(dirname($name));
$filename = dirname($name).'/'.$pre.'_'.basename($name).'.php';
} else {
$filename = $name.'.php';
}
if(is_file($path.'/'.$filename)) {
self::$_imports[$key] = true;
$rt = include $path.'/'.$filename;
return $rt;
} elseif(!$force) {
return false;
} else {
throw new Exception('Oops! System file lost: '.$filename);
}
}
return true;
}
//此時傳遞給core::import()的參數爲class/discuz/discuz_application.php,第2,3個參數爲默認的
$key = $folder.$name;
if(!isset(self::$_imports[$key])) {
若是包含了文件則不重複包含,包含事後都會把類名保存在$_imports[]數組內,因此開始判斷下這個鍵值是否已經存在,不存在執行下一步,而後下面的代碼也就是包含對應的PHP文件了,不詳細多說。
包含了文件後,程序繼續執行,由於此時discuz_application已經包含進來,能夠繼續執行如下函數。
self::$_app = discuz_application::instance();
執行discuz_application::instance()函數
----------------------------------------程序即將跳轉----------------------------------------
static function &instance() {
static $object;
if(empty($object)) {
$object = new self();//初始化一個類,如此便開始執行__construct()函數
}
return $object;
}
初始化一個類,$object=new self(),初始化後必然執行__construct()函數
----------------------------------------程序即將跳轉----------------------------------------
代碼以下
public function __construct() {
$this->_init_env();//環境設置
$this->_init_config();//配置
$this->_init_input();//設置GET,POST ,COOKIE
$this->_init_output();//rss charset GZIP等。
}
----------------------------------------程序即將跳轉----------------------------------------
$this->_init_env();//環境設置
代碼以下:
private function _init_env() {
error_reporting(E_ERROR);
if(PHP_VERSION < '5.3.0') {
set_magic_quotes_runtime(0);
}
define('MAGIC_QUOTES_GPC', function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc());
define('ICONV_ENABLE', function_exists('iconv'));
define('MB_ENABLE', function_exists('mb_convert_encoding'));
define('EXT_OBGZIP', function_exists('ob_gzhandler'));
define('TIMESTAMP', time());//記錄開始時間,沒刷新頁面都會執行
$this->timezone_set();//設置時區
//包含核心函數庫
if(!defined('DISCUZ_CORE_FUNCTION') && !@include(DISCUZ_ROOT.'./source/function/function_core.php')) {
exit('function_core.php is missing');
}
//內存設置爲128M
if(function_exists('ini_get')) {
$memorylimit = @ini_get('memory_limit');
if($memorylimit && return_bytes($memorylimit) < 33554432 && function_exists('ini_set')) {
ini_set('memory_limit', '128m');
}
}
define('IS_ROBOT', checkrobot());
//$GLOBALS爲全局變量數組,好比外部定義了$f00="123",在這裏經過$GLOBALS['foo']='123';
foreach ($GLOBALS as $key => $value) {
if (!isset($this->superglobal[$key])) {
$GLOBALS[$key] = null; unset($GLOBALS[$key]);//不明白爲什麼要清空$GLOBALS,彷佛是用本身的一套變量清空系統變量
}
}
global $_G;//超級大數組
$_G = array(
'uid' => 0,
'username' => '',
'adminid' => 0,
'groupid' => 1,
'sid' => '',
'formhash' => '',
'connectguest' => 0,
'timestamp' => TIMESTAMP,
'starttime' => microtime(true),
'clientip' => $this->_get_client_ip(),//獲取客戶端IP地址
'referer' => '',
'charset' => '',
'gzipcompress' => '',
'authkey' => '',
'timenow' => array(),
'widthauto' => 0,
'disabledwidthauto' => 0,
'PHP_SELF' => '',
'siteurl' => '',
'siteroot' => '',
'siteport' => '',
'pluginrunlist' => !defined('PLUGINRUNLIST') ? array() : explode(',', PLUGINRUNLIST),
'config' => array(),
'setting' => array(),
'member' => array(),
'group' => array(),
'cookie' => array(),
'style' => array(),
'cache' => array(),
'session' => array(),
'lang' => array(),
'my_app' => array(),
'my_userapp' => array(),
'fid' => 0,
'tid' => 0,
'forum' => array(),
'thread' => array(),
'rssauth' => '',
'home' => array(),
'space' => array(),
'block' => array(),
'article' => array(),
'action' => array(
'action' => APPTYPEID,
'fid' => 0,
'tid' => 0,
),
'mobile' => '',
'notice_structure' => array(
'mypost' => array('post','pcomment','activity','reward','goods','at'),
'interactive' => array('poke','friend','wall','comment','click','sharenotice'),
'system' => array('system','myapp','credit','group','verify','magic','task','show','group','pusearticle','mod_member','blog','article'),
'manage' => array('mod_member','report','pmreport'),
'app' => array(),
),
'mobiletpl' => array('1' => 'mobile', '2' => 'touch', '3' => 'wml','yes' => 'mobile'),
);
//dhtmlspecialchars 在function_core.php裏
$_G['PHP_SELF'] = dhtmlspecialchars($this->_get_script_url());
$_G['basescript'] = CURSCRIPT;//在運行首個PHP文件裏定義了,好比member.php裏定義了member
$_G['basefilename'] = basename($_G['PHP_SELF']);
$sitepath = substr($_G['PHP_SELF'], 0, strrpos($_G['PHP_SELF'], '/'));
if(defined('IN_API')) {
$sitepath = preg_replace("/\/api\/?.*?$/i", '', $sitepath);
} elseif(defined('IN_ARCHIVER')) {
$sitepath = preg_replace("/\/archiver/i", '', $sitepath);
}
$_G['isHTTPS'] = ($_SERVER['HTTPS'] && strtolower($_SERVER['HTTPS']) != 'off') ? true : false;
$_G['siteurl'] = dhtmlspecialchars('http'.($_G['isHTTPS'] ? 's' : '').'://'.$_SERVER['HTTP_HOST'].$sitepath.'/');
$url = parse_url($_G['siteurl']);
$_G['siteroot'] = isset($url['path']) ? $url['path'] : '';
$_G['siteport'] = empty($_SERVER['SERVER_PORT']) || $_SERVER['SERVER_PORT'] == '80' || $_SERVER['SERVER_PORT'] == '443' ? '' : ':'.$_SERVER['SERVER_PORT'];
if(defined('SUB_DIR')) {
$_G['siteurl'] = str_replace(SUB_DIR, '/', $_G['siteurl']);
$_G['siteroot'] = str_replace(SUB_DIR, '/', $_G['siteroot']);
}
$this->var = & $_G;
}
----------------------------------------程序即將跳轉----------------------------------------
$this->_init_env();//環境設置
$this->_init_config();//配置 $this->_init_input();//設置GET,POST ,COOKIE $this->_init_output();//rss charset GZIP等。