Blogger Information
Blog 91
fans 0
comment 0
visits 203487
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
ci框架源码解析
何澤小生的博客
Original
2608 people have browsed it
  1. index.php :入口文件
    |-->define('ENVIRONMENT')  |主要用于设置errors日志输出级别
    |-->$system_path |设置系统路径
    |-->设置BASEPATH、FCPATH、SYSDIR、APPPATH等    |设置路径信息变量,为加载相应文件信息准备
    |-->require_once BASEPATH.core/CodeIgniter.php | 最后加载CodeIgniter.php作为总控制器

  2. CodeIgniter.php加载过程,主要用于加载core核心目录下相应文件

    |-->require(BASEPATH.'core/Common.php');  |加载core目录下的Common文件,见2.1解析
    |-->require(APPPATH.'config/'.ENVIRONMENT.'/constants.php'); |加载constants目录,与开发环境无关时直接使用config目录下的constants目录
    |-->get_config(array('subclass_prefix' => $assign_to_config['subclass_prefix']));   |设置子文件,扩展类的前缀
    |-->$BM =& load_class('Benchmark', 'core');  |加载benchmark类,mark记录当前的时间
    |-->$EXT =& load_class('Hooks', 'core');     |加载core目录下的Hooks钩子类
    |-->$EXT->_call_hook('pre_system');  |调用_call_hook(pre_system),根据pre_system内部调用_run_hook执行钩子,在系统开始正式工作前作预处理
    |-->$CFG =& load_class('Config', 'core');    |继续执行core下的Config配置文件,
    |-->$CFG->_assign_to_config($assign_to_config); 
    |-->|$this->set_item($key, $val);      |解析指定给config的配置文件,实质为对config[]赋值
    |-->$UNI =& load_class('Utf8', 'core');      |加载了UTF-8编码类,CI_Utf8
    |-->$URI =& load_class('URI', 'core');       |加载core目录的URI类,CI_URI
    |-->$RTR =& load_class('Router', 'core');    |设置route路由及覆盖信息,见2.2解析
    |-->_set_routing()
    |-->_set_overrides()
    |-->$OUT =& load_class('Output', 'core');    |实例化输出类,加载core目录下的output文件
    |-->$OUT->_display_cache($CFG, $URI)         |判断是否存在页面缓存,是则输出文件
    |-->$SEC =& load_class('Security', 'core');  |加载core目录下的安全处理文件
    |-->$IN=& load_class('Input', 'core');      |实例化输入类,加载core目录下的input文件
    |-->$LANG =& load_class('Lang', 'core');     |加载语言类
    |-->require BASEPATH.'core/Controller.php';  |加载基本控制器类,见2.3解析
    |-->require APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php';  |尝试加载扩展的自定义子类控制器
    |-->include(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().'.php');  |加载自定义控制器下的控制器类
    |-->$BM->mark('loading_time:_base_classes_end'); |设定一个benchmark测试点
    |-->$class  = $RTR->fetch_class();    |分别获取uri地址的控制器类名和方法名
    |-->$method = $RTR->fetch_method();
    |-->if ( ! class_exists($class)              |判断方法及类是否合理
    OR strncmp($method, '_', 1) == 0
    OR in_array(strtolower($method), array_map('strtolower', get_class_methods('CI_Controller')))
    )
    |-->$EXT->_call_hook('pre_controller');      |处理器执行前进行预处理,并做benchmark设置
    |-->$CI = new $class();                      |获取执行的控制器实例,实例化构造器
    |-->$EXT->_call_hook('post_controller_constructor');  |实例化控制器类后的钩子处理
    |-->if (method_exists($CI, '_remap'))
    |-->$CI->_remap($method, array_slice($URI->rsegments, 2))  |如果控制器存在_remap()方法,则执行, 判断条件$CI为控制器类 
    |-->else |判断方法在类当中的存在似,如果不存在,则设置
    |-->call_user_func_array(array(&$CI, $method), array_slice($URI->rsegments, 2)); |最终传递参数供调用控制类方法
    |-->$BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_end'); |benchmark标记时间结束点
    |-->$EXT->_call_hook('post_controller');     |控制器生存周期,在控制器执行完成后执行后续操作
    |-->$OUT->_display();  |输出页面进行展示
    |-->$EXT->_call_hook('post_system');         |请求生存周期完成后的终结操作
    |-->$CI->db->close();                        |自动关闭数据库资源


    2.1 Core/Common.php加载
    |-->function is_php($version)                |用于比较版本号的函数
    |-->function is_really_writable($file)       |用于判断是否可以写文件,在不同的系统中可靠程度不同,
          W中通过判断is_readonly,U中如果safe_mode为开则不确定性
    |-->function load_class($class, $directory = 'libraries', $prefix = 'CI_')   |用于加载目录下的PHP文件的class类
    |-->foreach (array(APPPATH, BASEPATH) as $path)    |分别在application和system目录下轮循
    |-->file_exists($path.$directory.'/'.$class.'.php' |找到对应的PHP文件
    |-->require($path.$directory.'/'.$class.'.php');   |require加载对应的PHP文件内的类,加了前缀,此处可扩展
    |-->break;   |如正确加载则退出,否则继续尝试加载文件
    |-->file_exists(APPPATH.$directory.'/'.config_item('subclass_prefix').$class.'.php')  |自扩展的class类,如My_Test
    |-->if ($name === FALSE)   |如果$name不存在,则exit()退出 ,(在自定义类加载时,此处可作为扩展点,增加边际条件)
    |-->is_loaded($class);     |确类已经加载
    |-->$_classes[$class] = new $name();  |加载至静态的classes数祖中,用于缓存,调用时首先从classes中获取
    |-->function is_loaded($class = '')                      
    |-->设置$_is_loaded数祖,参数$class不为空,判断是否存在gf $_is_loaded,否则设置
    |-->function &get_config($replace = array())|用于获取Config的实例化文件
    |-->static $_config;       |定义config类型
    |-->$file_path = APPPATH.'config/config.php';      |确定application目录路径下定义的config.php的路径
    |-->require($file_path);   |加载application/config/config.php类
    |-->count($replace) > 0    |对于config.php中定义的变量,如果有replace,则逐个替代
    |-->foreach ($replace as $key => $val)
    |-->$config[$key] = $val;
    |-->return $_config[0] =& $config;   |最后返回定义的config的结果集
    |-->function config_item($item)    |配置选项,从config的数祖对象中返还特殊的配置项
    |-->$config =& get_config();
    |-->$_config_item[$item] = $config[$item];
    |-->function show_error            |用于错误信息输出
    |-->$_error =& load_class('Exceptions', 'core');    |加载Exceptions类
    |-->echo $_error->show_error($heading, $message, 'error_general', $status_code);  |直接输出错误
    |-->function show_404              |用于输出404页面,输出的错误信息页面可配置
    |-->function log_message           |用于写日志信息
    |-->$_log =& load_class('Log');
    |-->$_log->write_log($level, $message, $php_error);


    |-->function set_status_header     |用于输出状态的heade信息
    |-->function _exception_handler
    |-->function remove_invisible_characters
    |-->function html_escape           |过滤HTML变量
    |-->return htmlspecialchars($var, ENT_QUOTES, config_item('charset'));


    2.2 Router路由信息设置
    |-->_set_routing() 
    |-->$segments = array()    |根据目录,控制器,函数的触发器设定segment[]的uri段值,分别fetch()方法去取对象值
    |-->include(APPPATH.'config/routes.php');       |加载config下的routes文件
    |-->$this->routes          |设置routes数祖值,从config的route中获取
    |-->$this->default_controller       |设置routes的控制器值,从config的route中获取
    |-->return $this->_validate_request($segments); |验证uri的segment合法性
    |-->$this->uri->_remove_url_suffix();$this->uri->_reindex_segments();  |进一步清理解析uri,使segment从1开始x
    |-->_set_overrides()  |根据$routing的值,重新设定directory、controller、function参数
    |-->$this->set_directory($routing['directory']);
    |-->$this->set_class($routing['controller']);
    |-->$this->set_method($routing['function']);


    2.3 core/Controller.php加载
    |-->__construct()                                         |构造函数
    |-->self::$instance =& $this;  
    |-->foreach (is_loaded() as $var => $class)       |根据is_loaded()的信息加载相应的类
    |-->$this->$var =& load_class($class);   
    |-->$this->load =& load_class('Loader', 'core');  |加载core/Loader的php文件
    |-->$this->load->initialize();                    |主要用于autoload加载信息,如libraries、database等等
    |-->function &get_instance                                |返回当前实例
    |-->return self::$instance

扩展点:PHP自动加载机制在CodeIgniter中的应用
1.PHP自动加载机制:PHP5后,提供了类的自动加载机制,即类在加载时才被使用,即Lazy loading,共有二种方式
1.1: __autoload()通过扩展可实现,实质为设定规则加载相应路径的PHP文件(require、include方式)
1.2: 将autoload_func指向php文件,这个一般用c语言扩展实现 
  详见:http://blog.csdn.net/flyingpig4/article/details/7286438

2.在CodeIgniter中的应用
根据上述源码分析可知:CodeIgniter中所有的操作都是以Controller为起始,只需在Cotroller加载的过程中,
使__autoload()函数自动加载即可,目前的加载方式为在application/config/config.php中设置__autoload()
函数

Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post