CodeIgniter框架——源码分析之CodeIgniter.php

CodeIgniter.php中加载了很多外部文件,完成CI的一次完整流程。

<?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.1.4‘);
    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啦
    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()
    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();
    }
 
    $EXT->_call_hook(‘post_system‘);
        //关闭数据库的链接
    if (class_exists(‘CI_DB‘) AND isset($CI->db))
    {
        $CI->db->close();
    }

CodeIgniter框架——源码分析之CodeIgniter.php

时间: 2024-10-31 02:07:37

CodeIgniter框架——源码分析之CodeIgniter.php的相关文章

CodeIgniter框架——源码分析之入口文件index.php

CodeIgniter框架的入口文件主要是配置开发环境,定义目录常量,加载CI的核心类core/CodeIgniter.php. 源码分析如下: <?php //这个文件是入口,后期所有的文件都要在这里执行. /*----------------------------------------------- * 系统环境配置常量 * 能够配置错误显示级别 * ----------------------------------------------- * 默认情况下: * developmen

CodeIgniter框架——源码分析之Config.php

CI框架的配置信息被存储在$config数组中,我们可以添加自己的配置信息或配置文件到$config中: $this->config->load('filename'); //加载配置文件 $this->config->item('xxx'); //获取配置信息 当然也可以在autoload.php中设置默认加载! <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');   clas

YII框架源码分析(百度PHP大牛创作-原版-无广告无水印)

                        YII 框架源码分析             百度联盟事业部--黄银锋   目 录 1. 引言 3 1.1.Yii 简介 3 1.2.本文内容与结构 3 2.组件化与模块化 4 2.1.框架加载和运行流程 4 2.2.YiiBase 静态类 5 2.3.组件 6 2.4.模块 9 2.5 .App 应用   10 2.6 .WebApp 应用   11 3.系统组件 13 3.1.日志路由组件  13 3.2.Url 管理组件  15 3.3.异常

android 网络框架 源码分析

android 网络框架 源码分析 导语: 最近想开发一个协议分析工具,来监控android app 所有的网络操作行为, 由于android 开发分为Java层,和Native层, 对于Native层我们只要对linux下所有网络I/O接口进行拦截即可,对于java 层,笔者对android 网络框架不是很了解,所以这个工具开发之前,笔者需要对android 的网络框架进行一个简单的分析. 分析结论: 1. android 的网络框架都是基于Socket类实现的 2. java 层Socket

携程DynamicAPK插件化框架源码分析

携程DynamicAPK插件化框架源码分析 Author:莫川 插件核心思想 1.aapt的改造 分别对不同的插件项目分配不同的packageId,然后对各个插件的资源进行编译,生成R文件,然后与宿主项目的R文件进行id的合并. 要求:由于最终会将所有的资源文件id进行合并,因此,所有的资源名称均不能相同. 2.运行ClassLoader加载各Bundle 和MultiDex的思路是一样的,所有的插件都被加载到同一个ClassLoader当中,因此,不同插件中的Class必须保持包名和类名的唯一

介绍开源的.net通信框架NetworkComms框架 源码分析

原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架  作者是英国人  以前是收费的 售价249英镑 我曾经花了2千多购买过此通讯框架, 目前作者已经开源  许可是:Apache License v2 开源地址是:https://github.com/MarcFletcher/NetworkComms.Net 这个框架给我的感觉是,代码很优美,运行很稳定,我有一个项目使用此框架已经稳定运行1年多.这个框架能够

Android Small插件化框架源码分析

Android Small插件化框架源码分析 目录 概述 Small如何使用 插件加载流程 待改进的地方 一.概述 Small是一个写得非常简洁的插件化框架,工程源码位置:https://github.com/wequick/Small 插件化的方案,说到底要解决的核心问题只有三个: 1.1 插件类的加载 这个问题的解决和其它插件化框架的解决方法差不多.Android的类是由DexClassLoader加载的,通过反射可以将插件包动态加载进去.Small的gradle插件生成的是.so包,在初始

iOS常用框架源码分析

SDWebImage NSCache 类似可变字典,线程安全,使用可变字典自定义实现缓存时需要考虑加锁和释放锁 在内存不足时NSCache会自动释放存储的对象,不需要手动干预 NSCache的key不会被复制,所以key不需要实现NSCopying协议 第三方框架 网络 1.PPNetworkHelper 对AFNetworking 3.x 与YYCache的二次封装 简单易用,包含了缓存机制,控制台可以直接打印json中文字符 2..YTKNetwork 猿题库研发团队基于AFNetworki

linux设备驱动之misc驱动框架源码分析(一)

1.misc设备驱动框架源码部分是由内核开发者实现提供的,主要是创建misc类和为驱动开发者提供misc_register函数,来进行创建misc设备. 这部分的源码在/drvier/char/misc.c里,代码如下: /*  * linux/drivers/char/misc.c  *  * Generic misc open routine by Johan Myreen  *  * Based on code from Linus  *  * Teemu Rantanen's Micro