在member.php中有這么一段代碼:
- $mod = !in_array($discuz->var['mod'], $modarray) && (!preg_match('/^/w+$/', $discuz->var['mod']) || !file_exists(DISCUZ_ROOT.'./source/module/member/member_'.$discuz->var['mod'].'.php')) ? 'register' : $discuz->var['mod'];
從上面的紅色部分我們可以看出,這是一個3元運算,好了說重點:$discuz->var['mod']
首先從結構(->)上我們可以看出這是一個類的對象,但具體又是什么呢?我們來看$discuz,在member.php中有如下代碼:
- require './source/class/class_core.php';//引入class_core.php
- $discuz = C::app();//調用類C中的app方法
打開引入class_core.php文件,在該文件中有如下代碼:
- C::creatapp();
- class core{....}
- class C extends core {}
從上可知,類c繼承自core,所以C::creatapp()等價于core::creatapp(),現在來看core::creatapp()
- public static function creatapp() {
- if(!is_object(self::$_app)) {//判斷$_app是不是對象
- self::$_app = discuz_application::instance(); //如果不是對象,把類discuz_application中instance方法返回結果賦值給$_app;
- } //Vevb.com
- return self::$_app;//返回$_app
- }
這里又出現了一個類discuz_application,這個類定義在./source/class/discuz/discuz_application.php文件中,這里并沒有引用該文件,那么這個類是如何實現調用的呢?這里就涉及到了類的另外一種加載方法:類自動加載,當類discuz_application不存在是就會調用下面的:
- if(function_exists('spl_autoload_register')) {
- spl_autoload_register(array('core', 'autoload'));
- } else {
- function __autoload($class) {
- return core::autoload($class);
- }
- }
這里最終會執行的是ore::autoload().
這里都會調用 core::autoload('discuz_application');下面進入到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;
- }
- //執行后$file='class/discuz/application'
- try {
- //調用import方法
- self::import($file);
- return true;
- } catch (Exception $exc) {
- $trace = $exc->getTrace();
- foreach ($trace as $log) {
- if(emptyempty($log['class']) && $log['function'] == 'class_exists') {
- return false;
- }
- }
- discuz_error::exception_error($exc);
- }
- }
下面該進入self::import($file);self表示類本身,所以就等價于:core::import($file),也就是core::import('class/discuz/application'):
- public static function import($name, $folder = '', $force = true) {
- //分析傳入的參數$file,獲取類所在的文件名及路徑
- $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';
- }
- //確定文件名及路徑$filename=‘class/discuz/discuz_application.php’
- //引入文件
- if(is_file($path.'/'.$filename)) {
- include $path.'/'.$filename;
- self::$_imports[$key] = true;
- return true;
- } elseif(!$force) {
- return false;
- } else {
- throw new Exception('Oops! System file lost: '.$filename);
- }
- }
- return true;
- }
上面已近分析了discuz_application的自動加載,下面回到上面講到的self::$_app=discuz_application::instance()部分,現在已經知道這個類的位置,我們進入到/source/class/discuz/discuz_application.php,找到instance()方法:
- //這是個引用返回方法.
- static function &instance() {
- static $object;
- if(emptyempty($object)) {
- $object = new self();
- }
- return $object;
- }
- //通過這個方法將類discuz_application實例化,實例對象即:$object,那么self::$_app=discuz_application::instance()也就是相當于把對象賦給了self::$_app
至此,class_core.php文件中的C::creatapp();也就執行完畢了,現在回到member.php中.
- require './source/class/class_core.php';//引入class_core.php
- $discuz = C::app();//調用類C中的app方法
我們再來看看class_core.php文件中的C::app();
- public static function app() {
- return self::$_app;
- }
這個很簡單啦,就是返回其成員$_app,前面已近說了$_app就是類discuz_application的實例化.
ok,現在再來看$discuz = C::app(),這也就是說又將類discuz_application的實例化賦值給了$discuz,那么$discuz->var['mod']就很好理解了.
$discuz->var['mod']就表示類discuz_application的對象$discuz中的成員var['mod'];
我們再來看看類discuz_application中的var:
- global $_G;
- $_G = array(....此處省略5km代碼)
- //....此處再省略5km代碼
- if(defined('SUB_DIR')) {
- $_G['siteurl'] = str_replace(SUB_DIR, '/', $_G['siteurl']);
- $_G['siteroot'] = str_replace(SUB_DIR, '/', $_G['siteroot']);
- }
- $this->var = & $_G;
現在明白了var實際上就是全局變量$_G,至于鍵值可以mod在$_G是沒有的,繼續往下看:
在方法_init_input()中有如下定義:
$this->var['mod'] = empty($_GET['mod']) ? '' : dhtmlspecialchars($_GET['mod']);
又是一個3元運算符,這下徹底明白了var['mod']表示的就是url中變量mod參數,自此總算搞清楚了,在構造函數中包含了這個函數,所以實例化時就已經執行了這個函數:
- public function __construct() {
- $this->_init_env();
- $this->_init_config();
- $this->_init_input();
- $this->_init_output();
- }
這里有一個方法:dhtmlspecialchars():
- function dhtmlspecialchars($string) {
- if(is_array($string)) {
- foreach($string as $key => $val) {
- $string[$key] = dhtmlspecialchars($val);
- }
- } else {
- $string = str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $string);
- if(strpos($string, '
新聞熱點
疑難解答