zoukankan      html  css  js  c++  java
  • CodeIgniter框架——源码分析之CodeIgniter.php

      CodeIgniter.php可以说是CI的核心,大部分MVC的流程都是在这个文件夹中处理的,其中加载了很多外部文件,完成CI的一次完整流程。

      首先是定义了CI的版本(此处为CI 2.2.0),接下来是连续require了2个文件,core/Common.php,config/constants.php,接下来是设置错误处理。

    注:

      源码分析——CI到底做了些什么  

     1 CI的生命周期——system/core/CodeIgniter.php
     2 
     3 include('core/commons.php')
     4 载入 config/constant.php
     5 其他配置
     6 load benchmark,hooks
     7 hook: pre_system
     8 load Config, Utf8, URI, Router, Output
     9 hook: cache_override
    10     - output::_display_cache()
    11 load Security, Input, Lang
    12 hook: pre_controller
    13 $CI = new $class()
    14 hook: post_controller_constructor
    15 hook: post_controller
    16 hook: display_override
    17     - Output::_display()
    18 hook: post_system
    19 清理数据库连接

    源码分析如下:

    <?php  
    /**
     * 详见 http://www.phpddt.com/tag/codeIgniter/
     */
    //如果入口文件系统目录常量BASEPATH没定义,就挂了
    if ( ! defined('BASEPATH')) exit('No direct script access allowed');
            //定义常量:CI_VERSION,CI_CORE
        define('CI_VERSION', '2.2.0');
        define('CI_CORE', FALSE);
     
    /*
     *引入系统目录下core/Common.php,这里面全是CI的系统全局函数如is_php()、load_class()等
     */
        require(BASEPATH.'core/Common.php');
     
    /*
     *加载应用目录下的常量,注意如果存在相应的开发环境目录,则加载对应目录下的文件,ENVIRONMENT实在入口文件定义的
     */
     
        if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/constants.php'))
        {
            require(APPPATH.'config/'.ENVIRONMENT.'/constants.php');
        }
        else
        {
            require(APPPATH.'config/constants.php');
        }
     
    /*
     *_exception_handler函数是刚才在Common.php中加载的函数,用来拦截错误,记录日志,
     * set_error_handler是在_exception_handler函数中用load_class加载过来的。
     */
        set_error_handler('_exception_handler');
            //关闭magic quotes,关于这个的详细介绍请看:http://www.phpddt.com/php/php-magic-quotes.html
        if ( ! is_php('5.3'))
        {
            @set_magic_quotes_runtime(0); // Kill magic quotes
        }
     
    /*
     *子类前缀,很重要,也就是说你可以去扩展CI的核心类,后面说,默认配置应该是MY_
     */
            //看看你在index.php中是否定义前缀,没有定义的话就加载配置文件获知,get_config是Common.php中的全局函数
        if (isset($assign_to_config['subclass_prefix']) AND $assign_to_config['subclass_prefix'] != '')
        {
            get_config(array('subclass_prefix' => $assign_to_config['subclass_prefix']));
        }
     
    /*
     *php 程序运行默认是30s,这里用set_time_limt延长了,关于set_time_Limit() http://www.phpddt.com/php/set_time_limit.html
     * 扩展阅读,关于safe_mode:http://www.phpddt.com/php/643.html  ,你会完全明白的
     */
        if (function_exists("set_time_limit") == TRUE AND @ini_get("safe_mode") == 0)
        {
            @set_time_limit(300);
        }
     
    /*
     * 加载Benchmark,它很简单,就是计算任意两点之间程序的运行时间
     */
        $BM =& load_class('Benchmark', 'core');
        $BM->mark('total_execution_time_start');
        $BM->mark('loading_time:_base_classes_start');
     
            //加载钩子,后期会分析到,这玩意特好,扩展它能改变CI的运行流程
        $EXT =& load_class('Hooks', 'core');
     
            //这里就是一个钩子啦,其实就是该钩子程序在这里执行
        $EXT->_call_hook('pre_system');
     
            //加载配置文件,这里面都是一些加载或获取配置信息的函数
        $CFG =& load_class('Config', 'core');
     
        // 如果在index.php中也有配置$assign_to_config,则也把它加入到$CFG
        if (isset($assign_to_config))
        {
            $CFG->_assign_to_config($assign_to_config);
        }
     
            //加载utf8组件、URI组件、Router组件
        $UNI =& load_class('Utf8', 'core');
        $URI =& load_class('URI', 'core');
        $RTR =& load_class('Router', 'core');
        $RTR->_set_routing();
     
        //如果在index.php中定义了$routing,那么就会覆盖上面路由
        if (isset($routing))
        {
            $RTR->_set_overrides($routing);
        }
     
            //加载output输出组件,不然你怎么用$this->Load->view()啊
        $OUT =& load_class('Output', 'core');
     
            //又见钩子,这里你可以自己写钩子程序替代Output类的缓存输出
        if ($EXT->_call_hook('cache_override') === FALSE)
        {
            if ($OUT->_display_cache($CFG, $URI) == TRUE)
            {
                exit;
            }
        }
     
            //安全组件啦,防xss攻击啊,csrf攻击啊
            //关于xss攻击:http://www.phpddt.com/php/php-prevent-xss.html
            //关于csrf:攻击:http://www.phpddt.com/reprint/csrf.html
        $SEC =& load_class('Security', 'core');
     
            //加载输入组件,就是你常用的$this->input->post();等
        $IN    =& load_class('Input', 'core');
     
            //加载语言组件啦
        $LANG =& load_class('Lang', 'core');
     
            //引入CI的控制器父类
        require BASEPATH.'core/Controller.php';
     
        function &get_instance()
        {
            return CI_Controller::get_instance();
        }
     
            //当然你扩展了CI_Controller控制器的话,也要引入啦
        if (file_exists(APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php'))
        {
            require APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php';
        }
     
        //加载你自己应用中的控制器Controller,如果没有当然error啦
      //$RTR就是Router类的实例,Router类在构造实例的时候已经对请求的URL进行了解析,并得出对应的类名和方法名,下面就是通过fetch_class方法来获得对应的类名,如果这个控制器的文件存在,就加载这个文件,否则就报错。
    if ( ! file_exists(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().'.php')) { show_error('Unable to load your default controller. Please make sure the controller specified in your Routes.php file is valid.'); } include(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().'.php');   // 好的基础的类都加载完毕了,咱可以mark一下 $BM->mark('loading_time:_base_classes_end');   //路由获取了控制器名和方法名,比如说默认welcome/index $class = $RTR->fetch_class(); $method = $RTR->fetch_method(); //这里CI规定一般非公共的方法以_开头,下面是判断,如果URI不可访问就show_404(),这个404响应的页面也是CI自定义的,show_404()函数可以在Common.php中找到 if ( ! class_exists($class) OR strncmp($method, '_', 1) == 0 OR in_array(strtolower($method), array_map('strtolower', get_class_methods('CI_Controller'))) ) { if ( ! empty($RTR->routes['404_override'])) { $x = explode('/', $RTR->routes['404_override']); $class = $x[0]; $method = (isset($x[1]) ? $x[1] : 'index'); if ( ! class_exists($class)) { if ( ! file_exists(APPPATH.'controllers/'.$class.'.php')) { show_404("{$class}/{$method}"); }   include_once(APPPATH.'controllers/'.$class.'.php'); } } else { show_404("{$class}/{$method}"); } }   //又是钩子,该钩子发生在控制器实例化之前的 $EXT->_call_hook('pre_controller');   //又mark一个点 $BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_start'); //终于实例化控制器了 $CI = new $class();   //钩子,不想多说了 $EXT->_call_hook('post_controller_constructor');   /* * ------------------------------------------------------ * Call the requested method * ------------------------------------------------------ */ // Is there a "remap" function? If so, we call it instead if (method_exists($CI, '_remap')) { $CI->_remap($method, array_slice($URI->rsegments, 2)); } else { // is_callable() returns TRUE on some versions of PHP 5 for private and protected // methods, so we'll use this workaround for consistent behavior if ( ! in_array(strtolower($method), array_map('strtolower', get_class_methods($CI)))) { // Check and see if we are using a 404 override and use it. if ( ! empty($RTR->routes['404_override'])) { $x = explode('/', $RTR->routes['404_override']); $class = $x[0]; $method = (isset($x[1]) ? $x[1] : 'index'); if ( ! class_exists($class)) { if ( ! file_exists(APPPATH.'controllers/'.$class.'.php')) { show_404("{$class}/{$method}"); }   include_once(APPPATH.'controllers/'.$class.'.php'); unset($CI); $CI = new $class(); } } else { show_404("{$class}/{$method}"); } }   // 终于调用方法了,$this->load->view()把内容放到缓存区 call_user_func_array(array(&$CI, $method), array_slice($URI->rsegments, 2)); } $BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_end'); $EXT->_call_hook('post_controller');   //这里就是把缓存区的内容输出了 if ($EXT->_call_hook('display_override') === FALSE) { $OUT->_display(); }    
        //调用post_system的hook
    $EXT->_call_hook('post_system'); //关闭数据库的链接 if (class_exists('CI_DB') AND isset($CI->db)) { $CI->db->close(); }
  • 相关阅读:
    trackr: An AngularJS app with a Java 8 backend – Part III
    trackr: An AngularJS app with a Java 8 backend – Part II
    21. Wireless tools (无线工具 5个)
    20. Web proxies (网页代理 4个)
    19. Rootkit detectors (隐形工具包检测器 5个)
    18. Fuzzers (模糊测试器 4个)
    16. Antimalware (反病毒 3个)
    17. Debuggers (调试器 5个)
    15. Password auditing (密码审核 12个)
    14. Encryption tools (加密工具 8个)
  • 原文地址:https://www.cnblogs.com/xymqx/p/3921624.html
Copyright © 2011-2022 走看看