阅读core/CodeIgniter.php源代码的一处困惑
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;
$method = (isset($x) ? $x : '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}");
}
}
300多行,为什么先要unset($CI) 再重新实例化一遍?
应该是每次调用的情况都不一样,先销毁在实例化应该会更安全一下吧
(不懂乱说的哈)
因为第一次new 的$class 和第二次new的$class不同了
第一次出现$CI = new $class() ;
的地方是 307行左右。此时的$class 是经历过下面代码考验的。
if ( ! class_exists($class)
OR strncmp($method, '_', 1) == 0
OR in_array(strtolower($method), array_map('strtolower', get_class_methods('CI_Controller')))
)
这个判断筛选选出来的$class 是已经定义的,并且经过路由解析过来的函数不以 “_”开头,并且函数不在CI_Controller类声明的函数中(index,__construct ,get_instrance).
所以说白了,第一次$CI = new $class(); 此时实例化的对象$CI 是一个 有效的controller,但是此时不能确定$methon也有效。
第二次出现$CI = new $class() ;大概346行左右
是在判断$methon是否有效的时候,函数被检验无效了,而你又自定义了404错误页面
if ( ! in_array(strtolower($method), array_map('strtolower', get_class_methods($CI))))
{
if ( ! empty($RTR->routes['404_override']))//设置了自定义的404页面
{
$x = explode('/', $RTR->routes['404_override']);
$class = $x; //此时的$class 已经不是第一次实例化对象$CI时候的类了
$method = (isset($x) ? $x : 'index');
if ( ! class_exists($class)) //自定义错误处理页面的controller类没有定义
{
if ( ! file_exists(APPPATH.'controllers/'.$class.'.php'))
{
show_404("{$class}/{$method}");
}
include_once(APPPATH.'controllers/'.$class.'.php');
unset($CI); //307行那个由有效的controller实例化的对象$CI,在这里慷慨就义
$CI = new $class();//因为$method无效而创建的$CI被unset了,但是404的页面还要继续,404页面的controller在这里实例化了
本帖最后由 优雅de凋零 于 2013-5-16 13:56 编辑
第一次new 是 请求的类存在
请求的方法没有与CI_Controller中的方法发生冲突 以及 ...
就new 了
然后的检测是看 方法是否在类中存在
不存在就用 404_override 的处理过程
干掉不存在 请求方法的 类(类存在)
get_class_methods()
里面的参数可以是 类的名称字符串 也可以是 类的实例化对象
什么区别呢???
页:
[1]