日期:2014-05-17 浏览次数:20504 次
<?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
*/
// ------------------------------------
/**
* URI Class
*
* Parses 解析 URIs and determines routing
*
* @package CodeIgniter
* @subpackage Libraries
* @category URI
* @author ExpressionEngine Dev Team
* @link http://codeigniter.com/user_guide/libraries/uri.html
*/
class CI_URI {
/**
* List of cached uri segments
* 缓存uri段列表
* @var array
* @access public
*/
var $keyval = array();
/**
* Current uri string
* 当前uri字符串
* @var string
* @access public
*/
var $uri_string;
/**
* List of uri segments
* uri段列表
* @var array
* @access public
*/
var $segments = array();
/**
* Re-indexed list of uri segments
* Starts at 1 instead of 0
* 从1开始重新索引rui段列表
* @var array
* @access public
*/
var $rsegments = array();
/**
* Constructor
*
* Simply globalizes the $RTR object. The front
* loads the Router class early on so it's not available
* normally as other classes are.
*
* @access public
*/
function __construct()
{
$this->config =& load_class('Config', 'core');
log_message('debug', "URI Class Initialized");
}
// --------------------------------
/**
* Get the URI String
*
* @access private
* @return string
*/
function _fetch_uri_string()
{
// 下面的uri_protocol是在config.php里面的一个配置项,
// 其实是问你用哪种方式去检测uri的信息的意思,
// 默认是AUTO,自动检测,也就是通过各种方式检测,直至检测到,或者全部方式都检测完。。
if (strtoupper($this->config->item('uri_protocol')) == 'AUTO')
{
// Is the request coming from the command line?
// 开始尝试各种方式,主要有:命令行,REQUEST_URI, PATH_INFO, QUERY_STRING.
// 下面会多次出现$this->_set_uri_string($str)这个方法,这个方法没别的,就是把$str经过
// 过滤和修剪后值给$this->uri_string属性,在这里暂时可以理解为就是赋值。
// 如果脚本是在命令行模式下运行的话,那么参数就是通过$_SERVER['argv']来传递。下面的
// $this->_parse_cli_args();就是拿到符合我们需要的路由相关的一些参数
// 如果你没用命令行执行脚本的话,下面这个if暂时可以不用管。
// 这时候我们发现URI类用函数php_sapi_name()来测试不同的环境
// 在apache环境下面输出的结果是“apache2handler”;
// 在cgi模式下输出的结果是“cgi-fcgi”
// 要是在命令行模式下面运行的话,那么输出的结果是:”cli”
if (php_sapi_name() == 'cli' or defined('STDIN'))
{
$this->_set_uri_string($this->_parse_cli_args());
return;
}
// Let's try the REQUEST_URI first, this will work in most situations
// 查找uri
if ($uri = $this->_detect_uri())
{
// 如果找到uri 设置$this->uri_string
$this->_set_uri_string($uri);
return;
}
// Is there a PATH_INFO variable?
// Note: some servers seem 似乎 to have trouble 麻烦 with getenv() so we'll test it two ways
// 获取path $_SERVER['PATH_INFO'] 并不是每次请求都会有的所以当没有的时候使用getenv('PATH_INFO')
$path = (isset($_SERVER['PATH_INFO'])) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO');
if (trim($path, '/') != '' && $path != "/".SELF)
{
$this->_set_uri_string($path);
return;
}
// No PATH_INFO?... What about QUERY_STRING?
// 如果没有找到$_SERVER['PATH_INFO'] 我们使用QUERY_STRING
$path = (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');
if (trim($path, '/') != '')
{
$this->_set_uri_string($path);
return;
}
// As a last ditch effort lets try using the $_GET array
// 如果PATH_INFO和QUERY_STRING都没找到我们只能使用$_GET
if (is_array($_GET) && count($_GET) == 1 && trim(key($_GET), '/') != '')
{
$this->_set_uri_string(key($_GET));
return;
}
// We've exhausted all our options...
// 经过以上的努力我们还没有找到uri那么我们就真的找不到了
$this->uri_string = '';
return;
}
// 这里重新写了一遍获取uri_protocol 其实我觉得