当前位置:首页 > CMS教程 > Discuz > 列表

关于discuz X3.2中$discuz->var['mod']的理解

发布:smiling 来源: PHP粉丝网  添加日期:2015-09-30 11:14:25 浏览: 评论:0 

在member.php中有这么一段代码:

  1. $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中有如下代码:

  1. require './source/class/class_core.php';//引入class_core.php 
  2. $discuz = C::app();//调用类C中的app方法 

打开引入class_core.php文件,在该文件中有如下代码:

  1. C::creatapp(); 
  2. class core{....} 
  3. class C extends core {} 

从上可知,类c继承自core,所以C::creatapp()等价于core::creatapp(),现在来看core::creatapp()

  1. public static function creatapp() { 
  2. if(!is_object(self::$_app)) {//判断$_app是不是对象 
  3. self::$_app = discuz_application::instance(); //如果不是对象,把类discuz_application中instance方法返回结果赋值给$_app; 
  4. //phpfensi.com 
  5. return self::$_app;//返回$_app 

这里又出现了一个类discuz_application,这个类定义在./source/class/discuz/discuz_application.php文件中,这里并没有引用该文件,那么这个类是如何实现调用的呢?这里就涉及到了类的另外一种加载方法:类自动加载,当类discuz_application不存在是就会调用下面的:

  1. if(function_exists('spl_autoload_register')) { 
  2. spl_autoload_register(array('core''autoload')); 
  3. else { 
  4. function __autoload($class) { 
  5. return core::autoload($class); 

这里最终会执行的是ore::autoload().

这里都会调用 core::autoload('discuz_application');下面进入到autoload方法:

  1. public static function autoload($class) { 
  2. //分析类名,获取类所在的目录 
  3. $class = strtolower($class); 
  4. if(strpos($class'_') !== false) { 
  5. list($folder) = explode('_'$class); 
  6. $file = 'class/'.$folder.'/'.substr($classstrlen($folder) + 1); 
  7.  
  8. else { 
  9. $file = 'class/'.$class
  10. //执行后$file='class/discuz/application' 
  11. try { 
  12. //调用import方法 
  13. self::import($file); 
  14. return true; 
  15.  
  16. } catch (Exception $exc) { 
  17.  
  18. $trace = $exc->getTrace(); 
  19. foreach ($trace as $log) { 
  20. if(emptyempty($log['class']) && $log['function'] == 'class_exists') { 
  21. return false; 
  22. discuz_error::exception_error($exc); 

下面该进入self::import($file);self表示类本身,所以就等价于:core::import($file),也就是core::import('class/discuz/application'):

  1. public static function import($name$folder = ''$force = true) { 
  2. //分析传入的参数$file,获取类所在的文件名及路径 
  3. $key = $folder.$name
  4. if(!isset(self::$_imports[$key])) { 
  5. $path = DISCUZ_ROOT.'/source/'.$folder
  6. if(strpos($name'/') !== false) { 
  7. $pre = basename(dirname($name)); 
  8. $filename = dirname($name).'/'.$pre.'_'.basename($name).'.php'
  9. else { 
  10. $filename = $name.'.php'
  11. //确定文件名及路径$filename=‘class/discuz/discuz_application.php’ 
  12. //引入文件 
  13. if(is_file($path.'/'.$filename)) { 
  14. include $path.'/'.$filename
  15. self::$_imports[$key] = true; 
  16.  
  17. return true; 
  18. elseif(!$force) { 
  19. return false; 
  20. else { 
  21. throw new Exception('Oops! System file lost: '.$filename); 
  22. return true; 

上面已近分析了discuz_application的自动加载,下面回到上面讲到的self::$_app=discuz_application::instance()部分,现在已经知道这个类的位置,我们进入到/source/class/discuz/discuz_application.php,找到instance()方法:

  1. //这是个引用返回方法.
  2. static function &instance() {  
  3. static $object
  4. if(emptyempty($object)) { 
  5. $object = new self(); 
  6. return $object
  7. //通过这个方法将类discuz_application实例化,实例对象即:$object,那么self::$_app=discuz_application::instance()也就是相当于把对象赋给了self::$_app 

至此,class_core.php文件中的C::creatapp();也就执行完毕了,现在回到member.php中.

  1. require './source/class/class_core.php';//引入class_core.php 
  2. $discuz = C::app();//调用类C中的app方法 

我们再来看看class_core.php文件中的C::app();

  1. public static function app() { 
  2. 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:

  1. global $_G
  2. $_G = array(....此处省略5km代码) 
  3. //....此处再省略5km代码 
  4. if(defined('SUB_DIR')) { 
  5. $_G['siteurl'] = str_replace(SUB_DIR, '/'$_G['siteurl']); 
  6. $_G['siteroot'] = str_replace(SUB_DIR, '/'$_G['siteroot']); 
  7.  
  8. $this->var = & $_G

现在明白了var实际上就是全局变量$_G,至于键值可以mod在$_G是没有的,继续往下看:

在方法_init_input()中有如下定义:

$this->var['mod'] = empty($_GET['mod']) ? '' : dhtmlspecialchars($_GET['mod']);

又是一个3元运算符,这下彻底明白了var['mod']表示的就是url中变量mod参数,自此总算搞清楚了,在构造函数中包含了这个函数,所以实例化时就已经执行了这个函数:

  1. public function __construct() { 
  2. $this->_init_env(); 
  3. $this->_init_config(); 
  4. $this->_init_input(); 
  5. $this->_init_output(); 

这里有一个方法:dhtmlspecialchars():

  1. function dhtmlspecialchars($string) { 
  2. if(is_array($string)) { 
  3. foreach($string as $key => $val) { 
  4. $string[$key] = dhtmlspecialchars($val); 
  5. else { 
  6. $string = str_replace(array('&''"''<''>'), array('&''"''<''>'), $string); 
  7. if(strpos($string, '

Tags: discuz X3 2 $discuz->var

分享到: