打开admin.php
define('IN_ADMINCP', TRUE);
//定义常量IN_ADMINCP为true 这样在后面的每个页面都会判断
if(!defined('IN_DISCUZ') || !defined('IN_ADMINCP')) {
exit('Access Denied');
}
//防止外面直接访问后台文件,必须通过admin.php包含才可以访问其他文件,IN_DISCUZ在/sorce/class/class_core.php里定义的常量,后面几行马上包含该文件
define('NOROBOT', TRUE);
//定义常量NOROBOT为true,用于阻止搜索引擎爬虫抓取。
define('ADMINSCRIPT', basename(__FILE__));//admin.php
//__FILE__是获取文件磁盘位置详细路径,比如:D:\DedeAMPZ\web2013\discuz_video\upload\admin.php
//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等。