• 八)CodeIgniter源码分析之Config.php


      1 <?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
      2 
      3 // ------------------------------------------------------------------------
      4 
      5 /**
      6  * CodeIgniter Config Class
      7  */
      8 class CI_Config {
      9 
     10  /**
     11   * List of all loaded config values
     12   */
     13  var $config = array();
     14 
     15 
     16  /**
     17   * List of all loaded config files
     18   */
     19  var $is_loaded = array();
     20 
     21 
     22  /**
     23   * List of paths to search when trying to load a config file
     24   */
     25  var $_config_paths = array(APPPATH);
     26 
     27  /**
     28   * Constructor
     29   */
     30  function __construct()
     31  {
     32   $this->config =& get_config();
     33   log_message('debug', "Config Class Initialized");
     34 
     35   //在config/config.php里面有个配置项是base_url,它并不是必须配置项,如果没有配置,则系统就在这个地方
     36   //自己去它进行赋值。
     37   if ($this->config['base_url'] == '')
     38   {
     39    //一般来说,如果通过http访问网站的话,这个值都会有的。
     40    if (isset($_SERVER['HTTP_HOST']))
     41    {
     42     //判断是否通过https方式访问。
     43     $base_url = isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off' ? 'https' : 'http';
     44     $base_url .= '://'. $_SERVER['HTTP_HOST'];
     45     //去掉文件名部分。
     46     $base_url .= str_replace(basename($_SERVER['SCRIPT_NAME']), '', $_SERVER['SCRIPT_NAME']);
     47    }
     48 
     49    else
     50    {
     51     //如果发现没有$_SERVER['HTTP_HOST'],则直接设置为localhost
     52     $base_url = 'http://localhost/';
     53    }
     54 
     55    //保存到base_url中,以后像辅助函数uri_helper就可以通过base_url()调用出Config组件此值。
     56    $this->set_item('base_url', $base_url);
     57   }
     58  }
     59 
     60  // --------------------------------------------------------------------
     61 
     62  /**
     63   * Load Config File
     64   * 先解释一下load方法的参数,$file就是配置文件名。配置文件目录一般为应用目录(application)/config/下
     65   * 下面会有很多个针对不同方面配置的文件,而我们通过Config组件加载的配置信息都会保存在Config::$config这个
     66   * 属性里面,所以第二个参数$use_sections就是设置是否当前配置文件是否以独立一个数组的形式充当Config::$config
     67   * 的一个元素加入,如果为true,则$config是一个两层的数组,如果为false,则单纯将配置文件里面的配置信息合并。
     68   * 例如配置文件abc.php,如果为true,则会以$config['abc']['xxx']的形式保存,否则直接合并即会有
     69   * $config['xxx']。
     70   * 第三个参数只是设置要不要报错而已,如果为true,则只会返回false,如果为false则直接在函数执行时报错。
     71   */
     72  function load($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)
     73  {
     74   //接下来这一行代码是为了方便我们调用的时候既可以以xxx.php的形式传参,也可以只以xxx(无后缀)的形式。
     75   //另外如果$file为空,则默认是加载config.php
     76   $file = ($file == '') ? 'config' : str_replace('.php', '', $file);
     77   
     78   $found = FALSE;
     79   $loaded = FALSE;
     80 
     81   //这个$this->_config_paths默认只有应用目录application/
     82   foreach ($this->_config_paths as $path)
     83   {
     84    //分别从某特定环境的配置目录和默认的配置目录里面寻找。
     85    $check_locations = defined('ENVIRONMENT')
     86     ? array(ENVIRONMENT.'/'.$file, $file)
     87     : array($file);
     88 
     89    foreach ($check_locations as $location)
     90    {
     91     $file_path = $path.'config/'.$location.'.php';
     92 
     93     if (in_array($file_path, $this->is_loaded, TRUE))
     94     {
     95      $loaded = TRUE;
     96      continue 2;//如果是已经加载过了,那么在Config::$config里面理应当有,所以直接跳出最外层循环。
     97     }
     98 
     99     if (file_exists($file_path))
    100     {
    101      $found = TRUE;//如果找到了一个,就不再找了。所以相同的配置文件仅会有一个有效。
    102      break;
    103     }
    104    }
    105 
    106    //$found是用于判断在此$path里面,遍历上面的$check_locations有没有找到
    107    //而$load则是用于判断两层遍历以后,最终有没有把配置文件加载进来。
    108    if ($found === FALSE)
    109    {
    110     continue;
    111    }
    112 
    113    //配置文件就是在这个地方加载的,
    114    include($file_path);
    115 
    116    //下面这句可以看出,我们在包含的配置文件里面必须要有名为$config的数组。
    117    //如果配置信息格式不合法,看情况($$fail_gracefully的作用)处理错误。
    118    if ( ! isset($config) OR ! is_array($config))
    119    {
    120     
    121     if ($fail_gracefully === TRUE)
    122     {
    123      return FALSE;
    124     }
    125     show_error('Your '.$file_path.' file does not appear to contain a valid configuration array.');
    126    }
    127 
    128    //下面就是$use_sections的作用,根据它来规定当前加载的配置信息的保存形式。
    129    if ($use_sections === TRUE)
    130    {
    131     if (isset($this->config[$file]))
    132     {
    133      $this->config[$file] = array_merge($this->config[$file], $config);
    134     }
    135     else
    136     {
    137      $this->config[$file] = $config;
    138     }
    139    }
    140    else
    141    {
    142     $this->config = array_merge($this->config, $config);
    143    }
    144 
    145    //保存哪些文件已经加载过,下次再调用此load方法的时候,通过它来避免重复加载,减少不必要的操作。
    146    $this->is_loaded[] = $file_path;
    147    unset($config);
    148 
    149    $loaded = TRUE;
    150    log_message('debug', 'Config file loaded: '.$file_path);
    151    break;
    152   }
    153 
    154   //加载失败,按情况处理错误。
    155   if ($loaded === FALSE)
    156   {
    157    if ($fail_gracefully === TRUE)
    158    {
    159     return FALSE;
    160    }
    161    show_error('The configuration file '.$file.'.php'.' does not exist.');
    162   }
    163 
    164   //来到这里,说明了一切都很顺利,返回true。
    165   return TRUE;
    166  }
    167 
    168  // --------------------------------------------------------------------
    169 
    170  /**
    171   * Fetch a config file item
    172   * 取得某一配置项的内容,如果知道上面Config::load($file, $use_sections, $fail_gracefully);方法
    173   * 中$use_sections的意义的话,那个下面的$index意义就很容易理解了。
    174   */
    175  function item($item, $index = '')
    176  {
    177   if ($index == '')
    178   {
    179    if ( ! isset($this->config[$item]))
    180    {
    181     return FALSE;
    182    }
    183 
    184    $pref = $this->config[$item];
    185   }
    186   else
    187   {
    188    if ( ! isset($this->config[$index]))
    189    {
    190     return FALSE;
    191    }
    192 
    193    if ( ! isset($this->config[$index][$item]))
    194    {
    195     return FALSE;
    196    }
    197 
    198    $pref = $this->config[$index][$item];
    199   }
    200 
    201   return $pref;
    202  }
    203 
    204  // --------------------------------------------------------------------
    205 
    206  /**
    207   * Fetch a config file item - adds slash after item (if item is not empty)
    208   */
    209  //此方法仅仅是对配置信息进行一些修剪处理而已。
    210  function slash_item($item)
    211  {
    212   if ( ! isset($this->config[$item]))
    213   {
    214    return FALSE;
    215   }
    216   //如果此配置项仅仅是包含一些对配置无效的字符,则直接返回空。
    217   if( trim($this->config[$item]) == '')
    218   {
    219    return '';
    220   }
    221 
    222   //保证以一条/结尾。
    223   return rtrim($this->config[$item], '/').'/';
    224  }
    225 
    226  // --------------------------------------------------------------------
    227 
    228  /**
    229   * Site URL
    230   */
    231  //我们经常通过url_helper的site_url获得我们在项目中想要的路径,其实真正执行的是Config::site_url()这个方法。
    232  function site_url($uri = '')
    233  {
    234   //$uri参数实质可以是数组的
    235   
    236   
    237   if ($uri == '')
    238   {
    239    return $this->slash_item('base_url').$this->item('index_page');
    240   }
    241 
    242   //根据当前的路由格式返回相应的uri_string
    243   if ($this->item('enable_query_strings') == FALSE)
    244   {
    245    $suffix = ($this->item('url_suffix') == FALSE) ? '' : $this->item('url_suffix');
    246    return $this->slash_item('base_url').$this->slash_item('index_page').$this->_uri_string($uri).$suffix;
    247   }
    248   else
    249   {
    250    return $this->slash_item('base_url').$this->item('index_page').'?'.$this->_uri_string($uri);
    251   }
    252  }
    253 
    254  // -------------------------------------------------------------
    255 
    256  /**
    257   * Base URL
    258   */
    259  function base_url($uri = '')
    260  {
    261   return $this->slash_item('base_url').ltrim($this->_uri_string($uri),'/');
    262  }
    263 
    264  // -------------------------------------------------------------
    265 
    266  /**
    267   * Build URI string for use in Config::site_url() and Config::base_url()
    268   */
    269  protected function _uri_string($uri)
    270  {
    271   /**
    272    * 按当前规定路由格式,返回正确的uri_string.
    273    * 主要是如果当参数$uri是数组的时候的一些处理。
    274    */
    275   if ($this->item('enable_query_strings') == FALSE)
    276   {
    277    if (is_array($uri))
    278    {
    279     $uri = implode('/', $uri);
    280    }
    281    $uri = trim($uri, '/');
    282   }
    283   else
    284   {
    285    if (is_array($uri))
    286    {
    287     $i = 0;
    288     $str = '';
    289     foreach ($uri as $key => $val)
    290     {
    291      $prefix = ($i == 0) ? '' : '&';
    292      $str .= $prefix.$key.'='.$val;
    293      $i++;
    294     }
    295     $uri = $str;
    296    }
    297   }
    298      return $uri;
    299  }
    300 
    301  // --------------------------------------------------------------------
    302 
    303  /**
    304   * System URL
    305   */
    306  function system_url()
    307  {
    308   //厄,下面这行这么奇葩的代码,其实只是为拿到系统目录的路径而已。
    309   //正则部分是首先去掉BASEPATH中多余重复的“/”,然后再拆分为数组。最后通过end()函数来拿到系统目录名。
    310   $x = explode("/", preg_replace("|/*(.+?)/*$|", "\1", BASEPATH));
    311   return $this->slash_item('base_url').end($x).'/';
    312  }
    313 
    314  // --------------------------------------------------------------------
    315 
    316  /**
    317   * Set a config file item
    318   */
    319  function set_item($item, $value)
    320  {
    321   $this->config[$item] = $value;
    322  }
    323 
    324  // --------------------------------------------------------------------
    325 
    326  /**
    327   * Assign to Config
    328   */
    329  /**
    330   * 下面这个方法在CodeIgniter.php中调用过,是为把在index.php里设置的配置信息交给Config组件。 
    331   * 实质也是通过上面的Config::set_item();方法设置。
    332   */
    333  function _assign_to_config($items = array())
    334  {
    335   if (is_array($items))
    336   {
    337    foreach ($items as $key => $val)
    338    {
    339     $this->set_item($key, $val);
    340    }
    341   }
    342  }
    343 }
  • 相关阅读:
    网络流之转换为对偶图
    BZOJ 1051: [HAOI2006]受欢迎的牛(SCC)
    BZOJ[HNOI2005]狡猾的商人(差分约束)
    BZOJ [ZJOI2007]矩阵游戏(二分图匹配)
    BZOJ 1191: [HNOI2006]超级英雄Hero(二分图匹配)
    BZOJ 1270: [BeijingWc2008]雷涛的小猫(DP)
    BZOJ 1303: [CQOI2009]中位数图
    BZOJ [HNOI2006]鬼谷子的钱袋
    BZOJ1002 [FJOI2007]轮状病毒(最小生成树计数)
    A* 算法讲解
  • 原文地址:https://www.cnblogs.com/qxbj/p/4415222.html
Copyright © 2020-2023  润新知