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 }