php 路由实现类,基于fastroute
<?php
/**
* 核心路由查找器
*/
use FastRoute\RouteCollector;
use function FastRoute\simpleDispatcher;
use function FastRoute\cachedDispatcher;
class FastRoute {
public function __construct()
{
/** @var object $dispatcher 导入配置中的路由规则 */
// $dispatcher = simpleDispatcher(function (RouteCollector $r) {
$dispatcher = cachedDispatcher(function (RouteCollector $r) {
foreach ($GLOBALS['routeConfig'] as $key => $value) {
if ($key) {
$r->addGroup($key, function (RouteCollector $r) use ($key, $value) {
foreach ($value as $k => $v) {
// 如果控制器配置项为空时,默认根据路由获取控制器
$r->addRoute($v[0], $v[1], substr($key, 1) . ucfirst(empty($v[2])
? $v[2] = substr($v[1], 1) . 'Controller'
: $v[2]));
}
});
} else {
foreach ($value as $k => $v) {
$r->addRoute($v[0], $v[1], substr($v[2], 0, 1) === '/'
? substr(empty($v[2])
? $v[2] = substr($v[1], 1) . 'Controller'
: $v[2], 1)
: $v[2]);
}
}
}
} ,[
'cacheFile' => BASE_PATH . '/cache/route/route.cache', /* required */
'cacheDisabled' => DEBUG, /* optional, enabled by default */
]);
// 获取http传参方式和资源URI
$httpMethod = $_SERVER['REQUEST_METHOD'];
$uri = $_SERVER['REQUEST_URI'];
// 将url中的get传参方式(?foo=bar)剥离并对URI进行解析
if (false !== $pos = strpos($uri, '?')) {
$uri = substr($uri, 0, $pos);
}
$uri = rawurldecode($uri);
$routeInfo = $dispatcher->dispatch($httpMethod, $uri);
switch ($routeInfo[0]) {
// 使用未定义格式路由
case FastRoute\Dispatcher::NOT_FOUND:
if (!DEBUG) {
error(404,'404');
} else {
throw new \Whoops\Exception\ErrorException('未定义此路由或未在新建文件后使用composer dump-autoload');
}
break;
/**
* 请求的HTTP⽅法与配置的不符合
* HTTP规范要求405 Method Not Allowed响应包含“Allow:”头,
* 用以详细说明所请求资源的可用方法。
* 使用FastRoute的应用程序在返回405响应时,
* 应使用数组的第二个元素添加此标头。
*/
case FastRoute\Dispatcher::METHOD_NOT_ALLOWED:
$allowedMethods = $routeInfo[1];
header('HTTP/1.1 405 Method Not Allowed');
$allow = implode(',', $allowedMethods);
header('Allow:' . $allow);
$errorMsg = "请求方式非法,可使用的请求方式为: $allow";
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
error(405, $errorMsg);
} else {
exit($errorMsg);
}
break;
// 正常
case FastRoute\Dispatcher::FOUND:
$handler = $routeInfo[1];
$class = '\app\controllers\\' . ucfirst($handler);
$vars = $routeInfo[2];
$action = ucfirst(isset($vars['action'])
? $vars['action']
: 'index');
unset($vars['action']);
$_SESSION['route'] = [
'class' => substr($handler, 0, strpos(strtolower($handler), 'controller')),
'action' => strtolower(substr($action, 6))
];
// ... 调用$handler和$vars
echo call_user_func_array([
new $class,
$action
], $vars);
break;
}
}
}
路由配置文件
<?php
/**
* 路由配置文件
*/
return [
[
// 指向首页
[
['GET', 'POST'],
'/',
'HomeController'
],
[
['GET', 'POST'],
'/demo',
'DemoController'
],
// 指向adminController
[
'GET',
'/admin',
''
],
// 指向错误页面
[
'GET',
'/error/{code:\d+}',
'demoController'
],
[
'GET',
'/user[/{action}]',
'userController'
],
/*['GET','/user/{id:\d+}/{name}','userController'],*/
],
// 后台路由
'/admin' => [
// 指向adminUserController
[
'GET',
'/user',
''
]
]
];
评论 (0)