日期:2014-05-17  浏览次数:20515 次

CI框架源码阅读---------Router.php
<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
 * CodeIgniter
 *
 * An open source application development framework for PHP 5.1.6 or newer
 *
 * @package		CodeIgniter
 * @author		ExpressionEngine Dev Team
 * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc.
 * @license		http://codeigniter.com/user_guide/license.html
 * @link		http://codeigniter.com
 * @since		Version 1.0
 * @filesource
 */

// ------------------------------------

/**
 * Router Class
 *
 * Parses URIs and determines routing
 *
 * @package		CodeIgniter
 * @subpackage	Libraries
 * @author		ExpressionEngine Dev Team
 * @category	Libraries
 * @link		http://codeigniter.com/user_guide/general/routing.html
 */
class CI_Router {

	/**
	 * Config class
	 * 配置
	 * @var object
	 * @access public
	 */
	var $config;
	/**
	 * List of routes
	 * 路由列表,值来自APPPATH/config/route.php
	 * @var array
	 * @access public
	 */
	var $routes			= array();
	/**
	 * List of error routes
	 * 错误路由列表
	 * @var array
	 * @access public
	 */
	var $error_routes	= array();
	/**
	 * Current class name
	 * URI中的Controller
	 * @var string
	 * @access public
	 */
	var $class			= '';
	/**
	 * Current method name
	 * URI中显示调用的函数,默认为index()
	 * @var string
	 * @access public
	 */
	var $method			= 'index';
	/**
	 * Sub-directory that contains the requested controller class
	 * URI中现实的目录信息
	 * @var string
	 * @access public
	 */
	var $directory		= '';
	/**
	 * Default controller (and method if specific 确定的)
	 * 默认控制器
	 * @var string
	 * @access public
	 */
	var $default_controller;

	/**
	 * Constructor
	 *
	 * Runs the route mapping function.
	 * 加载并实例化config类和URI类
	 */
	function __construct()
	{
		$this->config =& load_class('Config', 'core');
		$this->uri =& load_class('URI', 'core');
		log_message('debug', "Router Class Initialized");
	}

	// --------------------------------

	/**
	 * Set the route mapping
	 *
	 * This function determines 确定,决心 what should be served based on the URI request,
	 * as well as any "routes" that have been set in the routing config file.
	 * 设置默认的路由信息,如果不存在控制器信息,则根据routes.php的设置来加载默认的控制器,
	 *
	 * @access	private
	 * @return	void
	 */
	function _set_routing()
	{
		// Are query strings enabled in the config file?  Normally CI doesn't utilize 运用 query strings
		// since URI segments are more search-engine friendly, but they can optionally 视情况 be used.
		// If this feature is enabled, we will gather  the directory/class/method a little differently

		// 如果项目是允许通过query_strings的形式,并且有通过$_GET的方式请求控制器的话,则以query_string形式路由
		// 上面这里为什么还要判断有没有通过get的方式指定控制器?
		// 其实是因为如果允许query_string的形式请求路由,但是却没有在APPPATH/config/config.php下配置 
		// controller_trigger,function_trigger,directory_trigger这三项的话,也是不能使用query_strings形式的
		// 此时,我们依然会采用“段”的形式。
		
		$segments = array();
		if ($this->config->item('enable_query_strings') === TRUE AND isset($_GET[$this->config->item('controller_trigger')]))
		{
			//取得目录名,控制名和方法名传递的变量名。这三项都是在config/config.php里面定义的。
			if (isset($_GET[$this->config->item('directory_trigger')]))
			{
				$this->set_directory(trim($this->uri->_filter_uri($_GET[$this->config->item('directory_trigger')])));
				$segments[] = $this->fetch_directory();
			}

			if (isset($_GET[$this->config->item('controller_trigger')]))
			{
				$this->set_class(trim($this->uri->_filter_uri($_GET[$this->config->item('controller_trigger')])));
				$segments[] = $this->fetch_class();
			}

			if (isset($_GET[$this->config->item('function_trigger')]))
			{
				$this->set_method(trim($this->uri->_filter_uri($_GET[$this->config->item('function_trigger')])));
				$segments[] = $this->fetch_method();
			}
		}

		// Load the routes.php file.
		// 根据当前环境加载APPPATH下面的routes.php
		if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/routes.php'))
		{
			include(APPPATH.'config/'.ENVIR