CodeIgniter框架源码分析第二篇CodeIgniter.php

1.php版本是否 <5.4, 过滤不安全的函数

/*
 * ------------------------------------------------------
 * Security procedures
 * ------------------------------------------------------
 */

if ( ! is_php('5.4'))

{
ini_set('magic_quotes_runtime', 0);


if ((bool) ini_get('register_globals'))
{
$_protected = array(
'_SERVER',
'_GET',
'_POST',
'_FILES',
'_REQUEST',
'_SESSION',
'_ENV',
'_COOKIE',
'GLOBALS',
'HTTP_RAW_POST_DATA',
'system_path',
'application_folder',
'view_folder',
'_protected',
'_registered'
);


$_registered = ini_get('variables_order');
foreach (array('E' => '_ENV', 'G' => '_GET', 'P' => '_POST', 'C' => '_COOKIE', 'S' => '_SERVER') as $key => $superglobal)
{
if (strpos($_registered, $key) === FALSE)
{
continue;
}


foreach (array_keys($$superglobal) as $var)
{
if (isset($GLOBALS[$var]) && ! in_array($var, $_protected, TRUE))
{
$GLOBALS[$var] = NULL;
}
}
}
}

}


2.注册错误处理函数

/*
 * ------------------------------------------------------
 *  Define a custom error handler so we can log PHP errors
 * ------------------------------------------------------
 */
set_error_handler('_error_handler');        //设置用户自定义的错误处理程序
set_exception_handler('_exception_handler');  //设置用户定义的异常处理函数。
register_shutdown_function('_shutdown_handler'); //注册一个会在php中止时执行的函数.注册一个 callback ,它会在脚本执行完成或者 exit() 后被调用。可以多次调用 register_shutdown_function() ,这些被注册的回调会按照他们注册时的顺序被依次调用。 如果你在注册的方法内部调用 exit(), 那么所有处理会被中止,并且其他注册的中止回调也不会再被调用。


3.设置扩展类前缀

/*
 * ------------------------------------------------------
 *  Set the subclass_prefix
 * ------------------------------------------------------
 *
 * Normally the "subclass_prefix" is set in the config file.
 * The subclass prefix allows CI to know if a core class is
 * being extended via a library in the local application
 * "libraries" folder. Since CI allows config items to be
 * overridden via data set in the main index.php file,
 * before proceeding we need to know if a subclass_prefix
 * override exists. If so, we will set this value now,
 * before any classes are loaded
 * Note: Since the config file data is cached it doesn't
 * hurt to load it here.
 */
if ( ! empty($assign_to_config['subclass_prefix']))
{
get_config(array('subclass_prefix' => $assign_to_config['subclass_prefix']));
}


4.Composer 自动加载处理

/*
 * ------------------------------------------------------
 *  Should we use a Composer autoloader?
 * ------------------------------------------------------
 */
if ($composer_autoload = config_item('composer_autoload'))
{
if ($composer_autoload === TRUE)
{
file_exists(APPPATH.'vendor/autoload.php')
? require_once(APPPATH.'vendor/autoload.php')
: log_message('error', '$config[\'composer_autoload\'] is set to TRUE but '.APPPATH.'vendor/autoload.php was not found.');
}
elseif (file_exists($composer_autoload))
{
require_once($composer_autoload);
}
else
{
log_message('error', 'Could not find the specified $config[\'composer_autoload\'] path: '.$composer_autoload);
}
}


5.计算执行耗时

/*
 * ------------------------------------------------------
 *  Start the timer... tick tock tick tock...
 * ------------------------------------------------------
 */
$BM =& load_class('Benchmark', 'core');
$BM->mark('total_execution_time_start');
$BM->mark('loading_time:_base_classes_start');


6.实例化钩子

/*
 * ------------------------------------------------------
 *  Instantiate the hooks class
 * ------------------------------------------------------
 */
$EXT =& load_class('Hooks', 'core');


7.调用钩子的pre_system函数

/*
 * ------------------------------------------------------
 *  Is there a "pre_system" hook?
 * ------------------------------------------------------
 */
$EXT->call_hook('pre_system');


8.实例化config类

/*
 * ------------------------------------------------------
 *  Instantiate the config class
 * ------------------------------------------------------
 *
 * Note: It is important that Config is loaded first as
 * most other classes depend on it either directly or by
 * depending on another class that uses it.
 *
 */
$CFG =& load_class('Config', 'core');


// Do we have any manually set config items in the index.php file?
if (isset($assign_to_config) && is_array($assign_to_config))
{
foreach ($assign_to_config as $key => $value)
{
$CFG->set_item($key, $value);
}
}


9.字符集相关设置

/*
 * ------------------------------------------------------
 * Important charset-related stuff
 * ------------------------------------------------------
 *
 * Configure mbstring and/or iconv if they are enabled
 * and set MB_ENABLED and ICONV_ENABLED constants, so
 * that we don't repeatedly do extension_loaded() or
 * function_exists() calls.
 *
 * Note: UTF-8 class depends on this. It used to be done
 * in it's constructor, but it's _not_ class-specific.
 *
 */
$charset = strtoupper(config_item('charset'));
ini_set('default_charset', $charset);


if (extension_loaded('mbstring'))
{
define('MB_ENABLED', TRUE);
// mbstring.internal_encoding is deprecated starting with PHP 5.6
// and it's usage triggers E_DEPRECATED messages.
@ini_set('mbstring.internal_encoding', $charset);
// This is required for mb_convert_encoding() to strip invalid characters.
// That's utilized by CI_Utf8, but it's also done for consistency with iconv.
mb_substitute_character('none');
}
else
{
define('MB_ENABLED', FALSE);
}


// There's an ICONV_IMPL constant, but the PHP manual says that using
// iconv's predefined constants is "strongly discouraged".
if (extension_loaded('iconv'))
{
define('ICONV_ENABLED', TRUE);
// iconv.internal_encoding is deprecated starting with PHP 5.6
// and it's usage triggers E_DEPRECATED messages.
@ini_set('iconv.internal_encoding', $charset);
}
else
{
define('ICONV_ENABLED', FALSE);
}


if (is_php('5.6'))
{
ini_set('php.internal_encoding', $charset);
}


10. 加载兼容性特征

/*
 * ------------------------------------------------------
 *  Load compatibility features
 * ------------------------------------------------------
 */


require_once(BASEPATH.'core/compat/mbstring.php');
require_once(BASEPATH.'core/compat/hash.php');
require_once(BASEPATH.'core/compat/password.php');
require_once(BASEPATH.'core/compat/standard.php');


11. 实例化utf8类

/*
 * ------------------------------------------------------
 *  Instantiate the UTF-8 class
 * ------------------------------------------------------
 */
$UNI =& load_class('Utf8', 'core');


12.实例化 URI 类

/*
 * ------------------------------------------------------
 *  Instantiate the URI class
 * ------------------------------------------------------
 */
$URI =& load_class('URI', 'core');


13.实例化路由

/*
 * ------------------------------------------------------
 *  Instantiate the routing class and set the routing
 * ------------------------------------------------------
 */
$RTR =& load_class('Router', 'core', isset($routing) ? $routing : NULL);


14.实例化输出类

/*
 * ------------------------------------------------------
 *  Instantiate the output class
 * ------------------------------------------------------
 */
$OUT =& load_class('Output', 'core');


15.有缓存就读取缓存

/*
 * ------------------------------------------------------
 * Is there a valid cache file? If so, we're done...
 * ------------------------------------------------------
 */
if ($EXT->call_hook('cache_override') === FALSE && $OUT->_display_cache($CFG, $URI) === TRUE)
{
exit;
}


16.实例化安全类,用于预防xss和csrf

/*
 * -----------------------------------------------------
 * Load the security class for xss and csrf support
 * -----------------------------------------------------
 */
$SEC =& load_class('Security', 'core');


17.实例化输入类,输入过滤

/*
 * ------------------------------------------------------
 *  Load the Input class and sanitize globals
 * ------------------------------------------------------
 */
$IN =& load_class('Input', 'core');


18.实例化语言类

/*
 * ------------------------------------------------------
 *  Load the Language class
 * ------------------------------------------------------
 */
$LANG =& load_class('Lang', 'core');


19.加载app controller 和自定义controller

/*
 * ------------------------------------------------------
 *  Load the app controller and local controller
 * ------------------------------------------------------
 *
 */
// Load the base controller class
require_once BASEPATH.'core/Controller.php';


/**
* Reference to the CI_Controller method.
*
* Returns current CI instance object
*
* @return CI_Controller
*/
function &get_instance()
{
return CI_Controller::get_instance();
}


if (file_exists(APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php'))
{
require_once APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php';
}


// Set a mark point for benchmarking
$BM->mark('loading_time:_base_classes_end');


20.路由检测

/*
 * ------------------------------------------------------
 *  Sanity checks
 * ------------------------------------------------------
 *
 *  The Router class has already validated the request,
 *  leaving us with 3 options here:
 *
 * 1) an empty class name, if we reached the default
 *    controller, but it didn't exist;
 * 2) a query string which doesn't go through a
 *    file_exists() check
 * 3) a regular request for a non-existing page
 *
 *  We handle all of these as a 404 error.
 *
 *  Furthermore, none of the methods in the app controller
 *  or the loader class can be called via the URI, nor can
 *  controller methods that begin with an underscore.
 */


$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);
}


21. controller执行前的钩子

/*
 * ------------------------------------------------------
 *  Is there a "pre_controller" hook?
 * ------------------------------------------------------
 */
$EXT->call_hook('pre_controller');


22. 实例化请求控制器

/*
 * ------------------------------------------------------
 *  Instantiate the requested controller
 * ------------------------------------------------------
 */
// Mark a start point so we can benchmark the controller
$BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_start');


$CI = new $class();


23.post_controller_constructor 钩子

/*
 * ------------------------------------------------------
 *  Is there a "post_controller_constructor" hook?
 * ------------------------------------------------------
 */
$EXT->call_hook('post_controller_constructor');


24.调用请求方法

/*
 * ------------------------------------------------------
 *  Call the requested method
 * ------------------------------------------------------
 */
call_user_func_array(array(&$CI, $method), $params);


// Mark a benchmark end point
$BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_end');


25.post_controller 钩子

/*
 * ------------------------------------------------------
 *  Is there a "post_controller" hook?
 * ------------------------------------------------------
 */

$EXT->call_hook('post_controller');


26.发送最终结果到浏览器

/*
 * ------------------------------------------------------
 *  Send the final rendered output to the browser
 * ------------------------------------------------------
 */
if ($EXT->call_hook('display_override') === FALSE)
{
$OUT->_display();
}


27.post_system 钩子

/*
 * ------------------------------------------------------
 *  Is there a "post_system" hook?
 * ------------------------------------------------------
 */
$EXT->call_hook('post_system');



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值