discuz admin.php,DISCUZ源码分析流程详细介绍【admin.php入口】【1】

打开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等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值