访问我们构建的mvc结构的网站时,我们的请求一般是这样的:
http://localhost/index.php/index/list
其中index.php后面紧跟的是控制器index和方法list,程序最终要实例化index控制器类,执行list 方法。
如何从上面的url请求中取出控制器和方法,就是接下来我们要做的事情。
// 路由处理
public function route()
{
if (isset($_SERVER['PATH_INFO'])) {
$arr = explode('/', ltrim($_SERVER['PATH_INFO'], '/'));
$controllerName = array_shift($arr);
$actionName = array_shift($arr);
}
$controllerName = empty($controllerName) ? $this->config['defaultController'] :$controllerName;
$actionName = empty($actionName) ? $this->config['defaultAction'] : $actionName;
// 判断控制器和操作是否存在
$controller = 'app\\controllers\\' . ucfirst($controllerName) . 'Controller';
if (!class_exists($controller)) {
exit($controller . '控制器不存在');
}
if (!method_exists($controller, $actionName)) {
exit($actionName . '方法不存在');
}
// 如果控制器和操作名存在,则实例化控制器,因为控制器对象里面
// 还会用到控制器名和操作名,所以实例化的时候把他们俩的名称也
// 传进去。结合Controller基类一起看
$dispatch = new $controller($controllerName, $actionName);
// $dispatch保存控制器实例化后的对象,我们就可以调用它的方法,
// 也可以像方法中传入参数,以下等同于:$dispatch->$actionName($param)
call_user_func_array(array($dispatch, $actionName), $_REQUEST);
}
首先,我们要对$_SERVER['PATH_INFO']有一个了解,当我们发送这样的请求时:http://127.0.0.1/mvc/public/index.php/index/show
我们使用print_r($_SERVER),输出如下:
上面的输出中倒数第五行就是PATH_INFO,所以通过$_SERVER['PATH_INFO'],可以获取index.php后面的包含控制器和方法名的字符串。
如果我们请求的是:http://127.0.0.1/mvc/public/index.php,则$_SERVER中不会有PATH_INFO的信息。
$arr = explode('/', ltrim($_SERVER['PATH_INFO'], '/')); $controllerName = array_shift($arr); $actionName = array_shift($arr);这几行代码可以考查各位的功底,课上会提问。
为什么会写下面的代码呢?
$controllerName = empty($controllerName) ? $this->config['defaultController'] :$controllerName; $actionName = empty($actionName) ? $this->config['defaultAction'] : $actionName;
$controller = 'app\\controllers\\' . ucfirst($controllerName) . 'Controller';这行代码主要构建带有命名空间的类名,比如:我们请求的是:http://127.0.0.1/mvc/public/index.php/index
后面我们要访问的就是: app\controller\indexController这个控制器
最不好理解的是下面两行代码
$dispatch = new $controller($controllerName, $actionName);call_user_func_array(array($dispatch, $actionName), $_REQUEST);第一句是实例化控制器的对象
第二句是调用控制器对象的方法,并传递参数
其中 $_REQUEST可以得到get请求或者post请求的数据,数据类型为数组