当前位置: 澳门新濠3559 > 编程 > 正文

让开发者尽快找出错误,     Common.php 负责加载

时间:2019-11-16 22:36来源:编程
    该文再而三上篇文章: CI框架浅析(豆蔻梢头卡塔 尔(阿拉伯语:قطر‎ 记一回填坑经历 在博主刚做事那会是如此区分分化景况sdk的安排。 在布置文件中定义四个有别于景况的

     该文再而三上篇文章: CI框架浅析(豆蔻梢头卡塔 尔(阿拉伯语:قطر‎

记一回填坑经历

在博主刚做事那会是如此区分分化景况sdk的安排。

  • 在布置文件中定义四个有别于景况的字段,举个例子叫做evmt,evmt有八个值,1是测量试验,2是明媒正娶。
  • 在配置到正式情状的时候和平运动维约定手动改一下evmt。那样作者就足以读取evmt的值,然后决定使用哪一种情况的sdk,那会自身被自身这种经验的主张给感动到了,认为本人好聪明。

展未来布置文件中山高校约正是如此

    //config.php中的配置
    $config['evmt']   = 1;  //1测试/2正式
    $config['wx_sdk'] =
    [
        1 => ['appid' => 'xxx', 'appkey'  => 'xxx'],
        2 => ['appid' => 'ccc', 'appkey'  => 'ccc'],
    ];


    //然后在业务逻辑我就通过读取evmt的值使用对应的sdk相关的配置,pay.php
    $appid   = $wx_sdk[$evmt]['appid'];
    $appkey  = $wx_sdk[$evmt]['appkey'];

那样的布置肖似能够消除业务难题,但是惊恐不已的梦就来了,终于有贰次大家在测量检验意况把富有功效都测验成功陈设到专门的学问遇到后,顾客举报说订单有标题,大家就在测量检验景况测了意识怎么测都没难点,花了快二个小时才发掘标题,原本由于配备到专门的学问境遇时evmt未有改变引致调用了测量检验蒙受sdk的安顿,那坑挖的呵呵。

因为在安排时手动校勘配置对于运营来讲难免会有脱漏,而且对于布署作者来讲便是自动化了,你令人怎么手动去改吧?
是人都会犯错误的,又不是机械能够机械性的劳作,既然机器能做的事务干嘛要人肉到场呢,写代码不正是为了活动化么?

借由此番事故本身就去留意看了下CI的文书档案,发未来CI框架已经提供了对情况的扶植。

        CodeIgniter 是叁个精致但功效强盛的 PHP 框架,作为一个轻易易行而“高雅”的工具包,它可以为开垦者们创建功能完备的 Web 应用程序。本身使用CI框架有意气风发段时间了,今后调节把该框架源码解析二回,掌握其构架的来意与娇小之处。深入分析完全体的源码后,作者才来总括CI框架的得失,甚至适用于怎么着处境开辟。

在CI框架的宗旨库中,CodeIgniter.php担负加载全体必要的类库,第叁个加载的是公家库 core/Common.php

多环境

近些日子CI最新的版本是 3.1.4, 4.0版本也就要揭橥。大家先剖判3.1.4本子,然后再看看4.0有哪些重大突破。

     Common.php 肩负加载以下公共艺术:

何以是多蒙受

多蒙受在CI框架里指的是您的四个开垦条件,日常我们能够把景况分为

  • 支付情形development
  • 测量检验意况testing
  • 正规情形production

CI框架中是透过index.php中的 ENVIRONMENT 常量来治本多情状,这么些常量的值是透过$_SERVER['CI_ENV']读取的,用该常量来保管多景况的配置的就轻便多了,只要求在application/config/建四个和ENVIRONMENT有关的目录,然后把相应的sdk配置文件放到对应的目录下就足以了。

例如

application/config/development/sdk_config.php
application/config/production/sdk_config.php

安插的时候读取各自意况下.htaccess文件中CI_ENV的值就能够(注意:安插时要将.htaccess忽略,免得被遮住),剩下的就提交CI本身去加载就好了。这样也就一蹴即至了大家地方遭遇了卓殊标题了。

既然如此多意况的田管是和安排有关的,那么接下去大家看下配置相关的源码深入分析。

率先是查看根目录下index.php文件了,首要定义了多少个常量:

方法名
注释
is_php($version)
判断$version是否小于或等于当前安装的PHP版本
is_really_writable($file)
判断该文件是否可写
load_class($class, $directory = 'libraries', $param = NULL)
加载类,但只能加载前缀为CI 的类,或前缀为自己配置的 $config['subclass_prefix'
is_loaded
返回已经加载类的数组
get_config(Array $replace = array())
加载 application/config/config.php 配置数组
application/config/ENVIRONMENT/config.php ENVIRONMENT为你开发的环境
config_item($item)
获取配置项的具体一项值
get_mimes()
获取config/mimes.php 的元数据数组
is_https()
判断是否是 https 加密协议
is_cli()
判断是否是在命令行执行
show_error()
加载 Exception,在自己的模板输出错误,然后exit
show_404($page = '', $log_error = TRUE)
加载 Exception,在自己的模板输出404错误
log_message($level, $message)
输出日志信息(不要把config.php 的log_threshold变量设 置为 4,太卡了,消耗太多的性能)
set_status_header($code = 200, $text = '')
设置http回应状态头
_error_handler( )
错误处理,加载Exceptions类,然后用日志输出错误,如果是验证的错误,则exit(1)退出程序。
_exception_handler($exception)
异常处理,加载Exceptions类,记录异常,然后 exit(1)退出。
_shutdown_handler()
宕机处理,不同的错误级别做相应的处理,调用_error_handler 方法处理
remove_invisible_characters()
移除不可见的字符
html_escape($var, $double_encode = TRUE)
html 转义
_stringify_attributes($attributes, $js = FALSE)
将数组等其它类型,转换成字符串类型。
function_usable($function_name)
方法可用,该方法只是暂时的,后期可能会移除。这方法需要加载Suhosin (一个PHP的补丁或拓展)

配置

那块重要看下配置文件加载,配置读取,配置安装那三局部的源码。

 

 

安排文件的加载

布局文件的加载是由此config对象(CI_Config.php)的load()方法完成的。

 $this->config->load($file, $use_sectipon=false, $fail_gracefully= false);

load()方法提供了五个参数

  • 先是个参数$file是要加载的配备文件。
  • 第一个参数 $use_sectipon是为着制止你在加载七个布局文件时大器晚成致数组的目录引起的冲突,如若设置为true,那么各种配置文件中的配置项会被贮存到以该配置文件名字为索引的数组中去。
  • 其五个参数$fail_gracefully是用以遏抑错误音讯,如若设置为true,当配置文件不设不常,不会报错。
public function load($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)
    {

        //解析出文件名
        $file = ($file === '') ? 'config' : str_replace('.php', '', $file);
        $loaded = FALSE;


        //遍历配置文件所在的目录,这里我们看到考虑到了多环境的配置'ENVIRONMENT.DIRECTORY_SEPARATOR.$file'
        foreach ($this->_config_paths as $path)
        {
            foreach (array($file, ENVIRONMENT.DIRECTORY_SEPARATOR.$file) as $location)
            {
                $file_path = $path.'config/'.$location.'.php';

                //is_loaded中存储了已经加载过的配置文件,如果发现已经被加载过,就不需要在往下查找了
                if (in_array($file_path, $this->is_loaded, TRUE))
                {
                    return TRUE;
                }

                //没有找到的话再次循环,去下一个目录中查找
                if ( ! file_exists($file_path))
                {
                    continue;
                }

                include($file_path);

                //找到后如果发现文件中的配置不是数组的话,根据$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.');
                }

                /*
                 |   将当前文件的配置和系统初始化已经加载的配置合并,
                 |
                 |   $use_sections的意思是否将文件中的配置存储到以文件名为索引的数组中去,
                 |   很明显看到$this->config是系统初始化的配置,那么$this->config是怎么来的?
                 |   这里先留下这个疑问,分析完load()方法我们再去看$this->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);
                }


                //加载成功该配置文件后再is_loaded数组中保存下
                $this->is_loaded[] = $file_path;
                $config = NULL;
                $loaded = TRUE;
                log_message('debug', 'Config file loaded: '.$file_path);
            }
        }

        //最后返回配置文件是否加载成功
        if ($loaded === TRUE)
        {
            return TRUE;
        }
        elseif ($fail_gracefully === TRUE)
        {
            return FALSE;
        }

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

在深入分析这段代码时还残余了三个问号,看样子貌似 $this->config 保存的是系统最早化的风度翩翩部分安顿,那今后就需求探视 $this->config 是怎么来的;查找引用开采 $this->config 是在构造方法中被赋值的。

public function __construct()
    {
        //获取系统初始化的配置。接下来分析get_config()这个方法你会看到系统初始化被加载的配置文件有哪些
        $this->config =& get_config();

        //base_url是你站点的域名,如果你没有设置的话,会根据请求解析出你的站点域名
        if (empty($this->config['base_url']))
        {
            if (isset($_SERVER['HTTP_HOST']) && preg_match('/^(([[0-9a-f:]+])|(d{1,3}(.d{1,3}){3})|[a-z0-9-.]+)(:d+)?$/i', $_SERVER['HTTP_HOST']))
            {
                $base_url = (is_https() ? 'https' : 'http').'://'.$_SERVER['HTTP_HOST']
                    .substr($_SERVER['SCRIPT_NAME'], 0, strpos($_SERVER['SCRIPT_NAME'], basename($_SERVER['SCRIPT_FILENAME'])));
            }
            else
            {
                $base_url = 'http://localhost/';
            }

            //解析出你的站点域名后,重设base_url
            $this->set_item('base_url', $base_url);
        }

        log_message('info', 'Config Class Initialized');
    }

留心:系统开首化的铺排加载是分两片段的,风姿洒脱部分是在get_config()方法中加载的,另大器晚成局地是写在autoload.php通过加载器在系统初叶化是加载的。

当今看下通过get_config()方法在系统起初化时加载了如何布署。

function &get_config(Array $replace = array())
    {
        //首先先定义一个静态变量$config,这也预示着该变量会被后文多次引用。
        static $config;

        //这里我们会发现,该方法知识加载了主配置文件config.php
        if (empty($config))
        {

            //--------------------------require主配置文件config.php并考虑的多环境-----------------------------------
            $file_path = APPPATH.'config/config.php';
            $found = FALSE;
            if (file_exists($file_path))
            {
                $found = TRUE;
                require($file_path);
            }

            // Is the config file in the environment folder?
            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); // EXIT_CONFIG
            }

            //如果主配置文件有问题的话,就中断整个程序。
            if ( ! isset($config) OR ! is_array($config))
            {
                set_status_header(503);
                echo 'Your config file does not appear to be formatted correctly.';
                exit(3); // EXIT_CONFIG
            }
        }

        //这里通过传入的参数动态修改某些配置项
        foreach ($replace as $key => $val)
        {
            $config[$key] = $val;
        }

        //最后将主配置文件config.php中的配置项返回
        return $config;
    }
}

大家来看get_config()方法只是加载了主配置文件config.php,而其余急需活动载入的陈设文件是在加载器(CI_Loader.php)中被加载的。

前边在加载器的源码解析中观察,加载器管理须要被自动载入的能源的逻辑是在_ci_autoloader()方法举办的,该措施中通过得到供给活动载入的布局文件,调用$this->config($file)方法,传入须要载入的铺排文件名,$this->config()方法内部你拜会到其最终调用了config(CI_Config)对象的load()方法,将配备文件传给了load()方法。

澳门新濠3559 1

image.png

理清楚$this->config是怎么来的,并且驾驭它保存了一切系统初始化的安排项后,那么对于设置配置和读取配置就很掌握了,正是操作$this->config罢了。

澳门新濠3559,1、ENVIRONMENT (开辟意况常量卡塔 尔(英语:State of Qatar),该常理四个值接受:

Common.php中也调用了 Exceptions.php :

读取配置项

读取配置是透过config对象的item()方法完结的

   $this->config->item('appid');

item方法的源码蛮轻松

    //读取配置项的时候考虑到你可能把配置存在以文件为索引的数组下,
    //所以提供了第二个参数$index做为读取配置的索引
    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;
    }

   a、development(默许值卡塔尔国:开荒形式,在该形式下,这肯定是应有尽量输出捕获的日志错误,让开荒者尽快寻觅荒诞,定位代码行,消逝难题。

方法名 注释
log_exception($severity, $message, $filepath, $line)
记录异常信息,保存在日志里
show_404($page = '', $log_error = TRUE)
记录错误的日志,且调用show_error()输出错误页面
show_error($heading, $message, $template = 'error_general', $status_code = 500)
找到对应的模板,然后输出错误的html页面
show_exception($exception)
输出异常的html页面
show_php_error($severity, $message, $filepath, $line)
本地PHP出错处理,输出相应的错误页面。

安装配置项

安装配置项是通过config对象的set_item()方法实现的

   $this->config->set_item('appid', 'xxx');

public function set_item($item, $value)
    {
        $this->config[$item] = $value;
    }

安插和多境况的源码剖判就到此地截止了,大家计算一下。

对此配置管理说最器重的是合情合理的读取配置,这里就涉及到多情形的处理,也见到CI框架提供了蛮便捷的多遇到管理。
而对此配置最初化大家看看是由两局地成功的,黄金时代部分是在get_config()中加载了主配置文件,另意气风发有的供给活动载入的布置文件是付出加载器管理的。

   b、production:坐褥情势,该格局下,不出口错误的消息给客户看,会跳转到一个要好的顾客错误提醒页面。

 

   c、testting: 该值与 2 是千篇风姿洒脱律的意义;

 

 

if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/constants.php'))
{
       require_once(APPPATH.'config/'.ENVIRONMENT.'/constants.php');
}

2、BASEPATH(基本路子卡塔尔国指向 项目标system目录,框架的核心库

从代码可见: 

 

       加载框架的自定义常量,可在applcation/config 创立差别条件目录,如development 与production,在此八个目录下,都创建constants.php,然后创设各碰着亟待的常量。从别的的代码计算来,能够依据开垦的景况,给与陈设差别常量,甚至config 的大概具有配置,让顾客在开辟照旧揭露的时候,配置分裂的音信。

3、应用软件PATH(应用路线卡塔尔指向application目录,不过你也能够订正该目录名

 

    最终黄金年代行 require_once BASEPATH.'core/CodeIgniter.php'; 引进框架的大旨库。

 

CodeIgniter.php 首要做了以下操作:

1、加载框架中的常量,即 application/config/constants.php

2、加载全局方法 system/core/common.php

3、全局变量安全筛选管理

4、设置程序不当、格外与奔溃的相当管理方法

5、加载子类的前缀

6、推断是还是不是利用自定义的自行加载

7、运转定时器,记录程序运维的岁月

8、开头化钩子(Hook卡塔 尔(阿拉伯语:قطر‎,且在各类环节预约义好钩子

9、加载配置文件 core/config,同期也加载顾客配置的config

10、加载字符集相关的类库

11、加载宽容性性格

12、开始化系统大旨库 core下的 Utf8、ULacrosseI、Router、Output、

Security、Input、Lang类,同期引进Controller.php文件

 

      最终分析相应的controller、方法与参数,推行相应的事情管理。

      下边包车型大巴字数,大家黄金时代 豆蔻年华的上书每一步的具体效果,以致为啥要如此做!

      接待关切自笔者,一齐研商框架的布置原理。

编辑:编程 本文来源:让开发者尽快找出错误,     Common.php 负责加载

关键词: