CI framework source code reading notes 7 configuration management components Config. php, ciconfig. php

Source: Internet
Author: User

CI framework source code reading notes 7 configuration management components Config. php, ciconfig. php

In a flexible and controllable Application, there will inevitably be a large number of controllable parameters (we call it configuration), for example, in the master configuration file of CI (here it refers to Application/Config. PHP file), there are multiple configurations:

$config['base_url']   = 'http://test.xq.com';$config['index_page'] = '';$config['uri_protocol']     = 'AUTO';$config['url_suffix'] = '.html';$config['language']  = 'english';$config['charset'] = 'UTF-8';$config['enable_hooks'] = FALSE;…………………………

In addition, CI allows you to put configuration parameters out of the main configuration file. For example, you can define your own configuration file as Config_app.php, and then load your configuration file in your application controller as follows:

$this->config->load('config_app');

How is CI managed with so many configuration items and configuration files? This is what we are tracking today: Config. php, the configuration management component of CI.

First look at the class diagram of this component:

Where:

_ Config_paths: Path of the configuration file to be searched. This refers to the APPPATH directory. Your configuration file should also be located under APPPATH.

Config: This array is used to store items of all configuration items.

Is_loaded: Stores a list Of all loaded configuration files.

_ Construct: Component constructor, mainly used to configure base_url

_ Assign_to_config: Allows the configuration items in index. php to overwrite the settings in the main configuration file.

_ Uri_string, site_url, base_url, system_url: URI, project path, and other related processing.

Load: Load the configuration file.

Item: Get configuration items

Slash_item: Same as item, the difference is that the "\" separator is added at the end. Generally, only site_url and base_url will require slash_item.

Next we will analyze the specific implementation of each method:

1. Component initialization _ construct

As we mentioned before when analyzing the Common. php global function, before the Config component is instantiated, all group configuration files are obtained by the get_config () function. When the Config component is instantiated, all configurations must be stored in your own private variable $ config for later access and processing:

$this->config =& get_config();

Because our applications often need to obtain the base_url value, and this value is not mandatory (the base_url in config can be set to null ), however, we do not want the value of base_url to be obtained to be null. Therefore, CI performs some processing on base_url during Config component initialization. This mainly occurs when base_url is set to null in Config. php:

(1 ). if $ _ SERVER ['HTTP _ host'] is set, base_url is set to Protocal (HTTP or https) + $ _ SERVER ['HTTP _ host'] + SCIRPT_PATH format:

$base_url = isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off' ? 'https' : 'http';$base_url .= '://'. $_SERVER['HTTP_HOST'];$base_url .= str_replace(basename($_SERVER['SCRIPT_NAME']), '', $_SERVER['SCRIPT_NAME']);

(2) If no, it is directly set to http: // localhost /:

$base_url = 'http://localhost/';

(3 ). at the same time, map the base_url configuration item to the configuration array for later access (We will map the set_item method later. Here we only need to know that it is added to the configuration item and will overwrite the old value ):

$this->set_item('base_url', $base_url);

Later, we will see that the base_url configuration item is required for many components. Therefore, it is understandable that CI spends a certain amount of effort to ensure the correctness of base_url.

2. load the configuration file

This is one of the core methods in the Config component. The signature of this function:

function load($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)

All parameters are optional.

Here we will briefly explain the meanings of the parameters:

$ FileThe configuration file to be loaded can contain a suffix or not. If this parameter is not specified, the Config. php file is loaded by default.

$ User_sections: Whether to use an independent section for the loaded configuration file. If you have defined your own configuration file, the configuration items in your configuration file may be different from those in Config. configuration item conflicts in the PHP file. You can specify $ section as true to avoid overwriting the configuration item.

$ Fail_gracefully: Processing when the configuration file to be loaded does not exist. Gracefully indicates elegant. If this parameter is set to true, only false is returned if the file does not exist, and no error is displayed.

The specific implementation of this method is as follows:

(1) configure file name preprocessing:

$file = ($file == '') ? 'config' : str_replace('.php', '', $file);

This $ file only contains the file name, not the extension. If this parameter is null, the Config. php configuration file is loaded by default. This also indicates that when we load our own configuration file:

$ This-> config-> load (""); and

$ This-> config-> load ("config") has the same effect, while:

$ This-> config-> load ("config_app") and

$ This-> config-> load ("config_app.php") has the same effect.

If $ use_sections is enabled, this $ file serves as the primary key of config.

(2). Search for and load the configuration file.

Before tracking implementation, explain several important parameters in the search and loading process:

(3) The specific search process is a dual foreach loop:

/* For path looping in config_paths */foreach ($ this-> _ config_paths as $ path) {/* for each location, that is, find the */foreach ($ check_locations as $ location) for the ENVIRONMENT/config/and config/directories respectively. {/* actual configuration file name */$ file_path = $ path. 'config /'. $ location. '. php ';
/* If it has been loaded, it will jump to the outermost loop. In fact, due to the _ config_paths setting, the entire loop will pop out */if (in_array ($ file_path, $ this-> is_loaded, TRUE) {$ loaded = TRUE; continue 2;}/* if the file exists, jump out of the current loop */if (file_exists ($ file_path) {$ found = TRUE; break;}/* If the configuration file is not found, continue the next loop. Similarly, due to the _ config_path setting, the entire loop will pop out */if ($ found = FALSE) {continue ;}}

(4) introduce the configuration file

By now, if the configuration file does not exist, both $ found and $ loaded are false. CI determines the processing method of the file that does not exist based on the fail_gracefully parameter. If the file exists, check the format of the configuration file:

/* Introduce the configuration file */include ($ file_path);/* Check the format of the configuration file, which also indicates that the configuration file should contain at least $ config array */if (! Isset ($ config) OR! Is_array ($ config) {if ($ fail_gracefully = TRUE) {return FALSE;} show_error ('your '. $ file_path. 'File does not appear to contain a valid configuration array. ');}

(5) Processing of use_sections Parameters

As mentioned above, if the use_secitons parameter is true, CI_Config will enable independent key storage for this configuration file. For example, we load the configuration file in the controller as follows:

$this->config->load("config_app",true);

The config array is in the following format:

[config] => Array(    [base_url] => http://test.xq.com    [index_page] =>    [uri_protocol] => AUTO    [url_suffix] => .html    [proxy_ips] =>    [web_akey] => yyyyyyyyyyyy    [config_app] => Array        (            [web_akey] => xxxxxxx            [web_skey] => xxxxxxxxxxxxxxxxxxx            [web_callback_url] => http://test.xq.com/            [sess_pre] => WEB_APP            [cart_min] => 1            [cart_max] => 999        ))

Conversely, if we do not specify use_sections, the array is stored as follows:

[config] => Array(    [base_url] => http://test.xq.com    [index_page] =>    [uri_protocol] => AUTO    [url_suffix] => .html    [web_akey] => xxxxxxx    [web_skey] => xxxxxxxxxxxxxxxxxxx    [web_callback_url] => http://test.xq.com/    [sess_pre] => WEB_APP    [cart_min] => 1    [cart_max] => 999)

This also means that if user_secitons is not enabled, if your configuration file has the same key as the main configuration file Config. php, the items in the main configuration file will be overwritten:

/* Enable separate keys to store loaded config */if ($ use_sections === TRUE) {if (isset ($ this-> config [$ file]) {$ this-> config [$ file] = array_merge ($ this-> config [$ file], $ config );} else {$ this-> config [$ file] = $ config;} else {/* executes merge and changes CI_Config :: config */$ this-> config = array_merge ($ this-> config, $ config );}

(6) handle errors

After a double loop is completed, if loaded is false, that is, if no configuration is loaded successfully, handle the error according to fail_gracefully:

/* Failed to load any configuration */if ($ loaded = FALSE) {if ($ fail_gracefully = TRUE) {return FALSE ;} show_error ('the configuration file '. $ file. '. php does not exist. ');}
3. Obtain the configuration item, slash_item

The item method is used to obtain specific configuration items in the configuration. The signature of the change method is as follows:

function item($item, $index = '')

Note: If you enable use-sections when loading the configuration file, you must specify the second parameter when using item () to obtain the configuration item, that is, the file name of the loaded configuration file (excluding the suffix ). To better understand this, we assume that the Config/directory has a configuration file: config. php and config_app.php, these two configuration files contain the same key web_akey, in config. in php, the configuration is:

$config['web_akey']  = 'yyyyyyyyyyyy';

In config_app.php, the configuration is:

$config['web_akey'] = 'xxxxxxx';

Now, use the use-sections method to load the config_app configuration file (config. php will be loaded when the Config component is initialized ):

$this->config->load("config_app",true);

Then obtain the web_akey configuration item in the controller:

echo "config_app:web_akey => ",$this->config->item("web_akey","config_app"),"<br/>";echo "config    :web_akey => ",$this->config->item("web_akey");

Actual result:

config_app:web_akey => xxxxxxxconfig :web_akey => yyyyyyyyyyyy

After understanding the principle, the implementation of this method is relatively simple:

Function item ($ item, $ index = '') {/* if use_sections is not set, search for the configuration item */if ($ index ='') in config '') {if (! Isset ($ this-> config [$ item]) {return FALSE;} $ pref = $ this-> config [$ item];} else {if (! Isset ($ this-> config [$ index]) {return FALSE;} if (! Isset ($ this-> config [$ index] [$ item]) {return FALSE;} $ pref = $ this-> config [$ index] [$ item];} /* unified return exit */return $ pref ;}

Slash_item is actually similar to the item () method, but he does not search for the user's configuration. In addition, he returns the configuration items in the main configuration file and adds a backslash at the end of the configuration item. this method is usually used to process the two configuration items base_url and index_page:

Source code:

Function slash_item ($ item) {/* No configuration item */if (! Isset ($ this-> config [$ item]) {return FALSE;}/* the configuration item is null */if (trim ($ this-> config [$ item]) = '') {return'';}/* remove the last excess "/", add "/" */return rtrim ($ this-> config [$ item], '/') at the end. '/';}
4. Obtain the site site_url, base_url, and system_url.

Here we will clarify the differences between these meanings:

echo "site_url  : ",$this->config->site_url("index/rain"),"</br>";echo "base_url  : ",$this->config->base_url("index/rain"),"<br/>";echo "system_url: ",$this->config->system_url();

The results are as follows:

site_url : http://test.xq.com/index/rain.htmlbase_url : http://test.xq.com/index/rainsystem_url: http://test.xq.com/system/

As you can see, site_url adds suffix (in Config/config. php configuration) after the url address (HA, if your uri has query string, then Ci always add suffix: http://test.xq.com/index/rain at the end? W=ss.html is not very strange .)

Base_url indicates that no suffix url is added.

System_url is a strange way to get the url path of the system. But in fact, because the system path does not directly execute the script, the actual usage of this method is unknown for the moment. Please advise if you have any children's shoes.

The specific implementation method is not described here. Directly paste the source code:

Function site_url ($ uri = '') {/* uri is not set, use base_url + index_page */if ($ uri = '') {return $ this-> slash_item ('base _ url '). $ this-> item ('index _ page');}/* enable_query_strings is not enabled. You can add a suffix */if ($ this-> item ('Enable _ query_strings ') = FALSE) {$ suffix = ($ this-> item ('url _ suffix ') = FALSE )? '': $ This-> item ('url _ suffix '); return $ this-> slash_item ('base _ url '). $ this-> slash_item ('index _ page '). $ this-> _ uri_string ($ uri ). $ suffix;}/* No. Do not add the suffix */else {return $ this-> slash_item ('base _ url '). $ this-> item ('index _ page '). '? '. $ This-> _ uri_string ($ uri) ;}}/* Get base_url, note the difference with site_url */function base_url ($ uri = '') {return $ this-> slash_item ('base _ url '). ltrim ($ this-> _ uri_string ($ uri), '/');}/* Get the system url */function system_url () {/* Get the system directory. BASEPATH:/search/xx/phpCode/CI/system/*/$ x = explode ("/", preg_replace ("| /*(. + ?) /* $ | "," \ 1 ", BASEPATH); return $ this-> slash_item ('base _ url '). end ($ x ). '/';}
5. Get URI String: _ uri_string

Both site_url and base_url call _ uri_string. What is the purpose of this function?

It is reasonable to say that the _ uri_string function should be completed by the URI component, but it is put in the Config component here. It seems that there is something wrong (in fact, _ uri_string serves the base_url and site_url exclusive services ).

For a uri like this:

array(    'p1' => 'param1',    'p2' => 'param2')

If enable_query_string is false, the format of _ uri_string after processing is as follows:

param1/param2

If enable_query_string is true, the processing format is as follows:

p1=param1&p2=param2

This is a common form (although ugly and SEO is not good. Source code:

Protected function _ uri_string ($ uri) {/* enable_query_strings is false, directly implode */if ($ this-> item ('Enable _ query_strings ') = FALSE) {if (is_array ($ uri) {$ uri = implode ('/', $ uri) ;}$ uri = trim ($ uri ,'/');} /* if NO, concatenate it into a format similar to param1 = param1 & param2 = param2 */else {if (is_array ($ uri) {$ I = 0; $ str = ''; foreach ($ uri as $ key => $ val) {/* do not need to add & */$ prefix = ($ I = 0) before the first parameter )? '': '&'; $ Str. = $ prefix. $ key. '= '. $ val; $ I ++;} $ uri = $ str ;}} return $ uri ;}
6. Set the configuration item set_item _ assign_to_config

In contrast to item (), set_item is used to set configuration items. If the configuration item already exists, it will be overwritten:

$this->config[$item] = $value;

_ Assign_to_config is the same as set_item. This method provides the array setting method (call set_item. We have explained CodeIgniter before. mentioned in the PHP file: the modification method can be in index. set independent configuration items in php and index. the configuration in php has a higher priority (will overwrite the configuration in the main configuration file ):

function _assign_to_config($items = array()){if (is_array($items)){foreach ($items as $key => $val){$this->set_item($key, $val);}}}

At this point, the basic parsing of the Config component is completed. Let's review the basic functions of the component:

Finally, I felt that a good Config component saves a lot of trouble.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.