CodeIgniter框架源码笔记(7)——强大的配置管理器:配置类Config.php

类结构及说明


config:Config类所有配置项都存储在 $config 的数组中,iterm()方法取值也是从这里取。

is_loaded:is_loaded是个数组,用当前上下文加载过的文件路径做数组元素。load文件过程中如果路径存在,则说明已加载该配置文件,就不重复加载了

_config_paths:默认值array(APPPATH)。配置文件存放路径。程序循环加载。

__construct():加载默认config.php中的配置。如果config['base_url']不存在,则重新根据当前$_SERVER中信息计算并设置。

load():加载自定义配置文件。

item():获取配置项。

slash_item():获取配置项,并在后面加“/”。

set_item():设置配置项。

base_url()、site_url()、system_url()、_uri_string():主要用于URL辅助函数调用。system_url()已经弃用。

综上,Config类作为配置管理类,有以下几个主要功能:
1、加载配置文件
2、获取配置项值
3、设置配置项(临时)
4、url处理,不明白怎么放这里

CodeIgniter 默认有一个主要的配置文件 application/config/config.php 。所有配置项都存储在 $config 的数组中。
可以往这个文件中添加自己的配置项,也可以创建自己的配置文件并保存到配置目录下,但必须保证配置文件数组名都叫$config。如:
$config["auth_key"]="1jcsxdl_ms";

配置目录下其它系统配置信息,如routes.php,memcached.php,database.php并不能由Config类管理。他们都是在需要的地方手工写一串代码加载,如:
if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/routes.php'))
{
    include(APPPATH.'config/'.ENVIRONMENT.'/routes.php');
}

一、加载配置文件。有两种途径:
1、手工方式:$this->config->load('filename');
(1).参数$file 配置文件的名称
,无需 .php 扩展名。当没有参数时,默认加载文件为config.php
$this->config->load()的效果和$this->config->load("config")以及$this->config->load("config.php")是一致的。
代码是这样实现的:$file = ($file === '') ? 'config' : str_replace('.php', '', $file);

(2).参数$use_sections 将第二个参数设置为 TRUE ,这样每个配置文件中的配置会被存储到以该配置文件名为索引的数组中去,如:
$this->config->load('blog_settings', TRUE);// $this->config['blog_settings'] = $config
取的时侯就要这样取了$site_name = $this->config->item('site_name', 'blog_settings');

if ($use_sections === TRUE)
{
    $this->config[$file] = isset($this->config[$file])
        ? array_merge($this->config[$file], $config)
        : $config;
}

可以从源码中看出使用了$file名作主键$this->config[$file]=....$config;

(3).参数$fail_gracefully用于抑制错误信息,当配置文件不存在时,不会报错
否则,将有两种可能触发错误函数show_error
一种是加载到的配置文件里没有叫$config的数组:
if ( ! isset($config) OR ! is_array($config))
{
    if ($fail_gracefully === TRUE)
    {
        return FALSE;
    }
    
}
一种是到最后,没有加载到任何文件
show_error('The configuration file '.$file.'.php does not exist.');

(4).代码中$this->is_loaded是个数组,用当前上下文加载过的文件路径做数组元素。load文件过程中如果路径存在,则说明已加载该配置文件,就不重复加载了
源码注释:
/**
 * Load Config File
 *
 * @param    string    $file            Configuration file name
 * @param    bool    $use_sections        Whether configuration values should be loaded into their own section
 * @param    bool    $fail_gracefully    Whether to just return FALSE or display an error message
 * @return    bool    TRUE if the file was loaded correctly or FALSE on failure
 */
public function load($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)
{
    //当没有参数时,默认加载文件为config.php
    //删除文件名中的".php"部分
    $file = ($file === '') ? 'config' : str_replace('.php', '', $file);
    $loaded = FALSE;

    //这一层循环是设置存放路径 ,其定义在public $_config_paths = array(APPPATH);
    foreach ($this->_config_paths as $path)
    {
        //这层循环用于设置当前文件和环境ENVIRONMENT下的文件两重路径
        foreach (array($file, ENVIRONMENT.DIRECTORY_SEPARATOR.$file) as $location)
        {
            //组合成文件路径
            $file_path = $path.'config/'.$location.'.php';
            //判断$this->is_loaded,如果加载过,直接返回TRUE
            if (in_array($file_path, $this->is_loaded, TRUE))
            {
                return TRUE;
            }
            //如果文件不存在,跳入下一个循环
            if ( ! file_exists($file_path))
            {
                continue;
            }
            //如果文件存在,则会执行到这里,加载进来
            include($file_path);
            //如果文件中没有定义$config数组,则产生报错,根据$fail_gracefully来判断是否做出错提示
            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.');
            }
            //正常加载到定义的$config数组后
            if ($use_sections === TRUE)
            {
                $this->config[$file] = isset($this->config[$file])
                    ? array_merge($this->config[$file], $config)
                    : $config;
            }
            else
            {
                $this->config = array_merge($this->config, $config);
            }
            //将配置文件路径放入$this->is_loaded数组,表明已经加载。
            $this->is_loaded[] = $file_path;
            $config = NULL;
            $loaded = TRUE;
            log_message('debug', 'Config file loaded: '.$file_path);
        }
    }
    //如果循环完都找不到文件,则$loaded为FALSE,找到了则为TRUE
    if ($loaded === TRUE)
    {
        return TRUE;
    }
    elseif ($fail_gracefully === TRUE)
    {
        return FALSE;
    }

    show_error('The configuration file '.$file.'.php does not exist.');
}

2、自动方式
如果发现有一个配置文件你需要在全局范围内使用,可以让系统自动加载它。 要实现这点,打开位于 application/config/ 目录下的 autoload.php 文件, 将配置文件添加到自动加载数组中。
这个流程说来话长,可以说是整个autoload机制的精华:
step1).Controller.php父控制器在构造方法中$this->load =& load_class('Loader', 'core');
step2).调用load初使化方法$this->load->initialize();
step3).initialize()调用的是$this->_ci_autoloader()方法
step4).遍历autoload.php中的$autoload['config']数组
step5).调用Config->load()方法加载数组值(配置文件名)

二、获取配置项值
获取某个配置项,使用如下方法:
$this->config->item('item_name');

假如在load时设置了第二个参数为true:
$this->config->load('weixin_auth', TRUE);
要获取weixin_auth.php中的配置项"token_key"怎么办?
可以$token_key = $this->config->item('token_key', 'weixin_auth');
也可以
$weixin_auth_config = $this->config->item('weixin_auth');
$token_key = $weixin_auth_config['token_key'];

item方法源码
public function item($item, $index = '')
{
    if ($index == '')
    {
        return isset($this->config[$item]) ? $this->config[$item] : NULL;
    }

    return isset($this->config[$index], $this->config[$index][$item]) ? $this->config[$index][$item] : NULL;
}

三、设置配置项
这个时临时的,就是通过函数访问并写入$this->config数组
public function set_item($item, $value)
{
    $this->config[$item] = $value;
}

四、构造函数
1、构造函数首先利用common.php中的公共函数get_config()将配置项加载至类属性$this->config数组
2、第二步设置正确的base_url,并将他放到$this->config配置数组中供调用
config.php中有一选项$config['base_url'] = 'http://www.example.com/';
如果该值不存在,系统就会通过$_SERVER['SERVER_ADDR']和$_SERVER['SCRIPT_NAME']来构造正确的$config['base_url']
if (empty($this->config['base_url']))
{
    if (isset($_SERVER['SERVER_ADDR']))
    {
        if (strpos($_SERVER['SERVER_ADDR'], ':') !== FALSE)
        {
            $server_addr = '['.$_SERVER['SERVER_ADDR'].']';
        }
        else
        {
            $server_addr = $_SERVER['SERVER_ADDR'];
        }

        $base_url = (is_https() ? 'https' : 'http').'://'.$server_addr
            .substr($_SERVER['SCRIPT_NAME'], 0, strpos($_SERVER['SCRIPT_NAME'], basename($_SERVER['SCRIPT_FILENAME'])));
    }
    else
    {
        $base_url = 'http://localhost/';
    }

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

五、site_url($uri = '', $protocol = NULL)和base_url($uri = '', $protocol = NULL)
主要用于URL辅助函数调用,因为与conifg体系无关,暂不做阐述
function base_url($uri = '', $protocol = NULL)
{
    return get_instance()->config->base_url($uri, $protocol);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值