CodeIgniter 的 URI.php 要照顾很多情况,所以显得有点复杂,我们可以简化一下,来理解这个框架的 URL 处理过程。
我们先设计detect_uri()这个函数把,这个函数作用是获取 uri ,并通过 uri 调用相应的方法。
function detect_uri() {
// $_SERVER['REQUEST_URI']: 访问此页面所需的URI
// $_SERVER["SCRIPT_NAME"]: 当前脚本的路径
if ( ! isset($_SERVER['REQUEST_URI']) OR ! isset($_SERVER['SCRIPT_NAME'])) {
return '';
}
$uri = $_SERVER['REQUEST_URI'];
if (strpos($uri, $_SERVER['SCRIPT_NAME']) === 0) {
//去掉共同部分,取得对路由有用的部分。
$uri = substr($uri, strlen($_SERVER['SCRIPT_NAME']));
}
//任何路由信息的传递,可以直接返回
if ($uri == '/' || empty($uri)) {
return '/';
}
// 如果 strpos($uri, $_SERVER['SCRIPT_NAME']) === 0和elseif都无法匹配的时候,
// 返回这个url的path部分。
$uri = parse_url($uri, PHP_URL_PATH);
// 将路径中的 '//' 或 '../' 等进行清理
return str_replace(array('//', '../'), '/', trim($uri, '/'));
}
有一点需要说明一下,就是 $_SERVER['REQUEST_URI'] 与 $_SERVER['SCRIPT_NAME'] 的区别。
注释里虽然有说明,我们这里举个例子吧。比如我们访问 http://www.nowamagic.net/MagicPHP/index.php/welcome/nowamagic/ 的时候:
REQUEST_URI:/MagicPHP/index.php/welcome/nowamagic/
SCRIPT_NAME:/MagicPHP/index.php
strpos() 函数返回字符串在另一个字符串中第一次出现的位置。算了,基本的函数用法还是不写了,反正 $uri = substr($uri, strlen($_SERVER['SCRIPT_NAME'])); 就是获得了 /welcome/nowamagic/ 这个部分,这部分对路由有用。
接下来需要提取 uri 中的分段信息
// 把uri_string拆成段(同时对各段进行过滤),保存到URI::$segments中。
function explode_segments()
{
foreach (explode('/', preg_replace("|/*(.+?)/*$|", "\\1", $this->uri_string)) as $val) {
$val = trim($val);
if ($val != '') {
$this->segments[] = $val;
}
}
}
就这么简单,现在在 index.php 只需要:
// 自动加载所需的类
require('core/Common.php');
// 加载 core/URI.php 类
$URI =& load_class('URI');
$CI = new $class();
print_r( $URI->rsegments );
就可以打印出 URI 所包含的类名与方法名了。自己写的简易框架运行如下:
有了类名与方法名,我们就可以通过 Router 调用到具体的类,并调用改类的方法。URI 说完了,接下来我们再看看 Router.php
这个类。