CI代码阅读
为什么选择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 override
elseif ( ! 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 1
if ( ! $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


浙公网安备 33010602011771号