PHP CodeIgniter框架源码解析   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.2Router路由信息设置 |-->_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() 函数

php codeigniter ext,PHP CodeIgniter框架源码解析相关推荐

  1. php实现推广海报,php微信推广海报PHP CodeIgniter框架源码解析

    PHP CodeIgniter框架源码解析 1.index.php :入口文件 |-->define('ENVIRONMENT') |主要用于设置errors日志输出级别 |-->$sys ...

  2. php manual 反射,Laravel框架源码解析之反射的使用详解

    本文实例讲述了Laravel框架源码解析之反射的使用.分享给大家供大家参考,具体如下: 前言 PHP的反射类与实例化对象作用相反,实例化是调用封装类中的方法.成员,而反射类则是拆封类中的所有方法.成员 ...

  3. php 框架源码分析,Laravel框架源码解析之模型Model原理与用法解析

    本文实例讲述了Laravel框架源码解析之模型Model原理与用法.分享给大家供大家参考,具体如下: 前言 提前预祝猿人们国庆快乐,吃好.喝好.玩好,我会在电视上看着你们. 根据单一责任开发原则来讲, ...

  4. Android经典著名的百大框架源码解析(retrofit、Okhttp、Glide、Zxing、dagger等等)

    我们Android程序员每天都要和源码打交道.经过数年的学习,大多数程序员可以"写"代码,或者至少是拷贝并修改代码.而且,我们教授编程的方式强调编写代码的艺术,而不是如何阅读代码. ...

  5. java 并发框架源码_Java并发编程高阶技术-高性能并发框架源码解析与实战

    Java并发编程高阶技术-高性能并发框架源码解析与实战 1 _0 Z' @+ l: s3 f6 r% t|____资料3 Z9 P- I2 x8 T6 ^ |____coding-275-master ...

  6. BAT高级架构师合力熬夜15天,肝出了这份PDF版《Android百大框架源码解析》,还不快快码住。。。

    前言 为什么要阅读源码? 现在中高级Android岗位面试中,对于各种框架的源码都会刨根问底,从而来判断应试者的业务能力边际所在.但是很多开发者习惯直接搬运,对各种框架的源码都没有过深入研究,在面试时 ...

  7. iOS开发之Masonry框架-源码解析

    Masonry是iOS在控件布局中经常使用的一个轻量级框架.Masonry让NSLayoutConstraint使用起来更为简洁.Masonry简化了NSLayoutConstraint的使用方式,让 ...

  8. iOS开发之Masonry框架源码解析

    Masonry是iOS在控件布局中经常使用的一个轻量级框架,Masonry让NSLayoutConstraint使用起来更为简洁.Masonry简化了NSLayoutConstraint的使用方式,让 ...

  9. Android开发神器:OkHttp框架源码解析

    前言 HTTP是我们交换数据和媒体流的现代应用网络,有效利用HTTP可以使我们节省带宽和更快地加载数据,Square公司开源的OkHttp网络请求是有效率的HTTP客户端.之前的知识面仅限于框架API ...

  10. axios网络请求框架源码解析

    早期axios0.1.0版本做了对IE浏览器与包含XmlHttpRequest的浏览器的支持.并且做了对请求参数拼接.Json对象序列化等基本功能. 到0.19.0版本时,内部请求已经变为了在Node ...

最新文章

  1. 如何重新创建mysql数据库_重新创建数据库与数据表《 MySQL 基础 》
  2. 算法串匹配C++实现字符串匹配的KMP算法
  3. eclipse总是自动跳到ThreadPoolExecutor解决办法
  4. spring项目概念-BeanFactoryApplicationContext
  5. 记录学习第三天---系统基础
  6. python requests_一起看看Python之Requests库
  7. 【渝粤题库】陕西师范大学500003 热力学与统计物理学 作业(专升本)
  8. IntellJ IDEA神器使用技巧
  9. 利用BioEdit软件进行短序列序列比对之查看突变位点
  10. 微信公众平台开发(14)--标签管理与用户标签管理
  11. 对决:腾讯对360摊牌
  12. __CTOR_LIST__和__DTOR_LIST__解释
  13. 红帽牵手阿里云,水到渠成的合作
  14. 属于python语言中合法的二进制整数是_以下选项属于 Python 整数类型的是( )
  15. python 计算两直线交点
  16. Java模拟拨打电话程序_java_编写android拨打电话apk应用实例代码,android 实现拨打电话的app,代 - phpStudy...
  17. Swagger2 3.0的使用
  18. idea报错Shorten the command line via JAR manifest or via a classpath file and rerun.
  19. MSYS2开发环境搭建
  20. eclipse的下方控制台不见了怎么调出来?

热门文章

  1. Spring Cloud Netflix 服务注册与发现 — Eureka 入门案例
  2. 关于数据库的练习题,关系代数
  3. Matlab分号的使用
  4. KEIL编程中如何重定义printf()函数,以便在后来的开发中使用此函数进行串口数据输出
  5. tplink怎么进去_怎么进入TP-Link路由器设置界面?
  6. Pycharm 用鼠标滚轮控制字体大小
  7. 研究生学位论文文献检索小技巧——妙用谷歌学术搜索
  8. Arduino串口通信
  9. Load Switch负载开关详解
  10. SIM900A模块发送AT指令“ AT+CPIN? “返回“ PH-NET PIN ”的解决方法