为什么选择CI 官网给出的理由
- 你想要一个小巧的框架;
- 你需要出色的性能;
- 你需要广泛兼容标准主机上的各种 PHP 版本和配置;
- 你想要一个几乎零配置的框架;
- 你想要一个不需使用命令行的框架;
- 你想要一个不想被编码规则的条条框框限制住的框架;
- 你对 PEAR 这种庞然大物不感兴趣;
- 你不想被迫学习一种新的模板语言(当然如果你喜欢,你可以选择一个模板解析器);
- 你不喜欢复杂,追求简单;
- 你需要清晰、完整的文档。
如果你用php 开发那么你一定希望程序能够快速,稳定,简单的搭建起来,相比其他框架CI 太简单了。
CI是一个入门框架。
CI 小巧精简也确定了他比其他框架快一点点。
0x01.入口文件定义了一堆常量 ,最后引入核心文件
require_once BASEPATH.'core/CodeIgniter.php';
0x002.在 CodeIgniter.php中拦截一些报错
set_error_handler('_error_handler');set_exception_handler('_exception_handler');register_shutdown_function('_shutdown_handler');
建立我们的主角 CI_Controller.然后大臣们也开始工作并注入到容器中.CI_Controller要做的就是控制反转。所以你可以在 controller 中使用 $this->input->get('');
$BM =& load_class('Benchmark', 'core');
$EXT =& load_class('Hooks', 'core');
$CFG =& load_class('Config', 'core');
$UNI =& load_class('Utf8', 'core');
$URI =& load_class('URI', 'core');
$OUT =& load_class('Output', 'core');
$IN =& load_class('Input', 'core');
$SEC =& load_class('Security', 'core');
$LANG =& load_class('Lang', 'core');
0x03.Router 开始工作
$e404 = FALSE;$class = ucfirst($RTR->class);$method = $RTR->method;if (empty($class) OR ! file_exists(APPPATH.'controllers/'.$RTR->directory.$class.'.php')){$e404 = TRUE;}else{require_once(APPPATH.'controllers/'.$RTR->directory.$class.'.php');if ( ! class_exists($class, FALSE) OR $method[0] === '_' OR method_exists('CI_Controller', $method)){$e404 = TRUE;}elseif (method_exists($class, '_remap')){$params = array($method, array_slice($URI->rsegments, 2));$method = '_remap';}elseif ( ! method_exists($class, $method)){$e404 = TRUE;}/*** DO NOT CHANGE THIS, NOTHING ELSE WORKS!** - method_exists() returns true for non-public methods, which passes the previous elseif* - is_callable() returns false for PHP 4-style constructors, even if there's a __construct()* - method_exists($class, '__construct') won't work because CI_Controller::__construct() is inherited* - People will only complain if this doesn't work, even though it is documented that it shouldn't.** ReflectionMethod::isConstructor() is the ONLY reliable check,* knowing which method will be executed as a constructor.*/elseif ( ! is_callable(array($class, $method))){$reflection = new ReflectionMethod($class, $method);if ( ! $reflection->isPublic() OR $reflection->isConstructor()){$e404 = TRUE;}}}if ($e404){if ( ! empty($RTR->routes['404_override'])){if (sscanf($RTR->routes['404_override'], '%[^/]/%s', $error_class, $error_method) !== 2){$error_method = 'index';}$error_class = ucfirst($error_class);if ( ! class_exists($error_class, FALSE)){if (file_exists(APPPATH.'controllers/'.$RTR->directory.$error_class.'.php')){require_once(APPPATH.'controllers/'.$RTR->directory.$error_class.'.php');$e404 = ! class_exists($error_class, FALSE);}// Were we in a directory? If so, check for a global overrideelseif ( ! empty($RTR->directory) && file_exists(APPPATH.'controllers/'.$error_class.'.php')){require_once(APPPATH.'controllers/'.$error_class.'.php');if (($e404 = ! class_exists($error_class, FALSE)) === FALSE){$RTR->directory = '';}}}else{$e404 = FALSE;}}// Did we reset the $e404 flag? If so, set the rsegments, starting from index 1if ( ! $e404){$class = $error_class;$method = $error_method;$URI->rsegments = array(1 => $class,2 => $method);}else{show_404($RTR->directory.$class.'/'.$method);}}if ($method !== '_remap'){$params = array_slice($URI->rsegments, 2);}
这个代码是从 配置中读取路由参数,然后根据uri 将请求路由到指定的 action 中,将逻辑交由action处理。
这个 action是被定义到继承CI_Controller的控制类中,所以他可以通过 $this 使用全局已经注入的依赖。
依赖注入。
0X04.非Controller中如何使用依赖,答案是还是通过CI_Controller。
get_instance() 可以直接拿到这个容器。可以在common.php 中使用依赖方法。
function &get_instance(){return CI_Controller::get_instance();}
就连CI中的Model 也是从CI_Controller中找依赖database