目录
创建编写功能路由文件,(演示:route/web.php、route/api.php)
文件的编写格式(可以对Route文件的make_dispatcher方法实现自定义)
入口文件处引入composer自动加载文件,并调用路由加载方法
GitHUb地址:https://github.com/nikic/FastRoute/tree/v1.3.0
引入nikic/fast-route包
# 本次引入的是1.3.0版本的composer包
composer require nikic/fast-route v1.3.0
编写路由配置加载方法
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2021/6/14
* Time: 0:35
*/
namespace App\Lib;
use App\Exception\MethodNotAllowedException;
use App\Exception\RouteNotFoundException;
use FastRoute\Dispatcher;
use FastRoute\RouteCollector;
use function FastRoute\simpleDispatcher;
class Route
{
public static function load()
{
// 获取已配置的路由列表
$routeFiles = glob(ROUTE_PATH.DIRECTORY_SEPARATOR.'*.php');
foreach ($routeFiles as $file) {
$routeFileList[] = require_once($file);
}
// 加载所有路由文件配置的路由
$dispatcher = self::make_dispatcher($routeFileList);
// Fetch method and URI from somewhere
$httpMethod = $_SERVER['REQUEST_METHOD'];
$uri = $_SERVER['REQUEST_URI'];
// Strip query string (?foo=bar) and decode URI
if (false !== $pos = strpos($uri, '?')) {
$uri = substr($uri, 0, $pos);
}
$uri = rawurldecode($uri);
// 路由调度
$routeInfo = $dispatcher->dispatch($httpMethod, $uri);
switch ($routeInfo[0]) {
case Dispatcher::NOT_FOUND: // 找不到请求方法
// ... 404 Not Found
throw new RouteNotFoundException("请求方法不存在:{$uri}");
break;
case Dispatcher::METHOD_NOT_ALLOWED: // 请求类型错误
$allowedMethods = $routeInfo[1];
// ... 405 Method Not Allowed
throw new MethodNotAllowedException("请求类型错误({$httpMethod}),当前方法允许请求类型({$allowedMethods[0]})");
break;
case Dispatcher::FOUND: // 找到请求方法:调用方法即可
$handler = $routeInfo[1];
$vars = $routeInfo[2];
call_user_func([new $handler[0],$handler[1]],$vars);
break;
}
}
private static function make_dispatcher($routeFileList)
{
return simpleDispatcher(function(RouteCollector $router) use($routeFileList) {
foreach ($routeFileList as $routeFile) {
if (isset($routeFile['prefix'])) {
$routers = $routeFile[0];
$router->addGroup($routeFile['prefix'],function(RouteCollector $router) use($routers) {
if ($routers) {
foreach ($routers as $routeItem) {
$router->addRoute(strtoupper($routeItem[0]),$routeItem[1],$routeItem[2]);
} unset($routeItem);
}
});
} else {
if ($routeFile) {
foreach ($routeFile as $routeItem) {
$router->addRoute(strtoupper($routeItem[0]),$routeItem[1],$routeItem[2]);
} unset($routeItem);
}
}
} unset($routeFile);
});
}
}
涉及到的exception类写法
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2021/6/14
* Time: 0:05
*/
namespace App\Exception;
use Throwable;
class MethodNotAllowedException extends \Exception
{
public function __construct($message = "", $code = 0, Throwable $previous = null)
{
parent::__construct($message, $code, $previous);
}
}
创建编写功能路由文件,(演示:route/web.php、route/api.php)
文件的编写格式(可以对Route文件的make_dispatcher方法实现自定义)
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2021/6/13
* Time: 15:58
*/
// 不分组格式
return [
['GET','/api/hello',[\App\Controller\TestController::class,'index']],
];
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2021/6/13
* Time: 15:58
*/
// 分组格式
return [
'prefix' => '/',
[
['get','users',[\App\Controller\TestController::class,'index']],
]
];
入口文件处引入composer自动加载文件,并调用路由加载方法
<?php
// 定义目录常量
define('ROOT_DOCUMENT_PATH',dirname(__DIR__) . DIRECTORY_SEPARATOR);
// 自动加载文件
require_once(ROOT_DOCUMENT_PATH.'vendor/autoload.php');
// 设置异常集中处理类
set_exception_handler([\App\ExceptionHandle::class,'handle']);
// 加载路由配置文件
\App\Lib\Route::load();
测试
测试控制器
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2021/6/13
* Time: 16:04
*/
namespace App\Controller;
class TestController extends Controller
{
public function index()
{
echo 1111;
}
}