使用Composer从零开发一个简单的restful框架(05)-路由分组
路由分组
新建core/Route.php
,内容如下
<?php
namespace core;
class Route {
private string $group; //分组
private array $routes = []; //分组下的路由, 包括分组
public function __construct(string $group) {
$this->group = $group;
}
public function getGroup(): string {
return $this->group;
}
public function getRoutes(): array {
return $this->routes;
}
public function addRoute(string $method, string $uri, \Closure | string $cb): void {
$method = strtoupper($method);
slash_add($uri);
$item = new RouteItem($method, $uri, $cb);
$this->routes[] = $item;
}
public function addChild(Route $child): void {
$this->routes[] = $child;
}
}
编辑core/Router.php
,内容如下
<?php
namespace core;
class Router {
private Route $curr; //当前路由(路由分组开始时会切换, 分组代码执行完后再切换回来)
public function __construct() {
// 根路由
$this->curr = new Route('/');
// 加载路由文件(路由文件使用 $router 访问)
$router = $this;
foreach (glob(PATH_ROUTE . '*.php') as $routeFile) {
require_once $routeFile;
}
}
// 开始路由处理
public function routing(Request $request, Response $response): void {
$uri = $request->getUri();
slash_add_end($uri);
$this->dispatch($this->curr, $request->getMethod(), $uri, $request, $response);
$response->send();
}
// 路由分组
public function group(string $group, \Closure $cb): void {
$lastRoute = $this->curr;
slash_add_head($group);
$route = new Route($group);
$this->curr->addChild($route);
$this->curr = $route;
call_user_func($cb, $this);
$this->curr = $lastRoute;
}
public function get(string $uri, \Closure | string $cb): void {
$this->curr->addRoute('get', $uri, $cb);
}
public function post(string $uri, \Closure | string $cb): void {
$this->curr->addRoute('post', $uri, $cb);
}
public function put(string $uri, \Closure | string $cb): void {
$this->curr->addRoute('put', $uri, $cb);
}
public function delete(string $uri, \Closure | string $cb): void {
$this->curr->addRoute('delete', $uri, $cb);
}
public function patch(string $uri, \Closure | string $cb): void {
$this->curr->addRoute('patch', $uri, $cb);
}
public function options(string $uri, \Closure | string $cb): void {
$this->curr->addRoute('options', $uri, $cb);
}
public function any(string $uri, \Closure | string $cb): void {
$methods = ['get', 'post', 'put', 'delete', 'patch', 'options'];
foreach ($methods as $method) {
$this->curr->addRoute($method, $uri, $cb);
}
}
private function dispatch(Route $route, string $method, string $uri, Request $request, Response $response): void {
$group = $route->getGroup();
// 分组不会有命名参数, 不包含直接返回
if (!str_starts_with($uri, $group)) return;
$uri = substr($uri, strlen($group));
slash_add_head($uri);
$routes = $route->getRoutes();
foreach ($routes as $item) {
if ($item instanceof RouteItem) {
if ($method == $item->method && $uri == $item->uri) {
($item->cb)($request, $response);
return;
}
} else {
$this->dispatch($item, $method, $uri, $request, $response);
}
}
}
}
编辑route/test.php
,内容如下
<?php
use core\Request;
use core\Response;
use core\Router;
/** @var Router $router */
$router->get('/', function(Request $request, Response $response) {
$response->text('from /');
});
$router->get('/test', function(Request $request, Response $response) {
$response->text('from /test');
});
$router->get('/test2', function(Request $request, Response $response) {
$response->text('from /test2');
});
$router->group('group', function(Router $router) {
$router->get('', function(Request $request, Response $response) {
$response->text('from /group');
});
$router->get('test', function(Request $request, Response $response) {
$response->text('from /group/test');
});
});
测试
浏览器访问路由对应链接
本作品采用《CC 协议》,转载必须注明作者和本文链接