CI定义了一些面向过程的全局函数,这些函数是运行框架必须依赖的。

is_php($version)

这个函数是用来判断当前PHP版本是否大于某个特定版本的

function is_php($version)
{
    static $_is_php;
    $version = (string) $version;

    if ( ! isset($_is_php[$version]))
    {
        $_is_php[$version] = version_compare(PHP_VERSION, $version, '>=');
    }

    return $_is_php[$version];
}

可以看到,这个函数本身是对version_compare的封装,但是利用静态属性$_is_php对判断结果进行缓存。利用静态属性对结果进行缓存不仅应用在面向过程的函数中,还可以应用在类中。

get_config

看到这个函数你可能会想到Config类,你可能会问既然有了Config类,为啥需要这个方法。事情是这样的,要config类工作,我们需要考虑加载可能出现的子类,因而需要获得subclass_prefix这个config项目,于是我们陷入了死循环。我考虑的一个解决方案是在CI_Config这个基类上添加静态方法,这样不需要实例化,不需要考虑subclass_prefix了。我的这个方案相当于是把get_config这个全局方法封装到了Config类上。

function &get_config(Array $replace = array())
{
    // 缓存结果
    static $config;

    // 没有缓存的结果才去加载对应的config文件
    if (empty($config))
    {
        $file_path = APPPATH.'config/config.php';
        $found = FALSE;
        if (file_exists($file_path))
        {
            $found = TRUE;
            require($file_path);
        }

        // 根据环境加载相应的config
        if (file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/config.php'))
        {
            require($file_path);
        }
        elseif ( ! $found)
        {
            set_status_header(503);
            echo 'The configuration file does not exist.';
            exit(3);
        }

        if ( ! isset($config) OR ! is_array($config))
        {
            set_status_header(503);
            echo 'Your config file does not appear to be formatted correctly.';
            exit(3);
        }
    }

    // 替代旧的config,虽然很少用到
    foreach ($replace as $key => $val)
    {
        $config[$key] = $val;
    }

    return $config;
}

这个函数的主要作用是加载config数据,特殊情况下可能会更新这个config数组

config_item

function config_item($item)
{
    static $_config;

    if (empty($_config))
    {
        // 引用不能直接赋给静态属性,用一个array绕过这个问题
        $_config[0] =& get_config();
    }

    return isset($_config[0][$item]) ? $_config[0][$item] : NULL;
}

这个函数是用来获取某个特定的config项目的,依赖于get_config方法。

load_class

这个函数是用来加载CI生命周期中核心类的实例的。

function &load_class($class, $directory = 'libraries', $param = NULL)
{
    // 缓存实例化的类
    static $_classes = array();

    // 如果已实例化,返回已经实例化的类
    if (isset($_classes[$class]))
    {
        return $_classes[$class];
    }

    $name = FALSE;

    // 查找是否存在框架定义的类
    foreach (array(APPPATH, BASEPATH) as $path)
    {
        if (file_exists($path.$directory.'/'.$class.'.php'))
        {
            $name = 'CI_'.$class;

            if (class_exists($name, FALSE) === FALSE)
            {
                require_once($path.$directory.'/'.$class.'.php');
            }

            break;
        }
    }

    // 查找是否有开发者扩展的类
    if (file_exists(APPPATH.$directory.'/'.config_item('subclass_prefix').$class.'.php'))
    {
        $name = config_item('subclass_prefix').$class;

        if (class_exists($name, FALSE) === FALSE)
        {
            require_once(APPPATH.$directory.'/'.$name.'.php');
        }
    }

    if ($name === FALSE)
    {
        set_status_header(503);
        echo 'Unable to locate the specified class: '.$class.'.php';
        exit(5);
    }

    // 记录该类已被加载
    is_loaded($class);

    // 实例化
    $_classes[$class] = isset($param)
        ? new $name($param)
        : new $name();

    // 返回实例化的类
    return $_classes[$class];
}

function &is_loaded($class = '')
{
    static $_is_loaded = array();

    if ($class !== '')
    {
        $_is_loaded[strtolower($class)] = $class;
    }

    return $_is_loaded;
}

results matching ""

    No results matching ""