FastD Routing 是一个简单而强大的 PHP 路由器,支持路由嵌套、动态路由、模糊路由、中间件等功能。它依赖于 Http 组件,遵循 PSR-7 和 PSR-15 标准。
通过 Composer 安装:
Composer require "fastd/routing"
use FastD\Http\ServerRequest;
use FastD\Routing\RouteCollection;
use Zend\Diactoros\Response;
$collection = new RouteCollection();
$collection->addRoute('GET', '/', function (ServerRequest $request, $handler) {
return new Response(200, [], 'hello world');
});
$route = $collection->match(new ServerRequest('GET', '/')); // \FastD\Routing\Route
// 执行路由回调
$response = call_user_func_array($route->getCallback(), [$request, $handler]);
echo $response->getBody();use FastD\Http\ServerRequest;
use FastD\Routing\RouteCollection;
use Zend\Diactoros\Response;
$collection = new RouteCollection();
$collection->addRoute('GET', '/user/{name}', function (ServerRequest $request, $handler) {
$name = $request->getAttribute('name');
return new Response(200, [], 'hello ' . $name);
});
$route = $collection->match(new ServerRequest('GET', '/user/john'));
// 获取匹配的参数
$params = $route->getParameters(); // ['name' => 'john']use FastD\Http\ServerRequest;
use FastD\Routing\RouteCollection;
use Zend\Diactoros\Response;
$collection = new RouteCollection();
// 数字参数约束
$collection->addRoute('GET', '/user/{id:[0-9]+}', function (ServerRequest $request, $handler) {
$id = $request->getAttribute('id');
return new Response(200, [], 'user id: ' . $id);
});
// 字母参数约束
$collection->addRoute('GET', '/profile/{name:[a-zA-Z]+}', function (ServerRequest $request, $handler) {
$name = $request->getAttribute('name');
return new Response(200, [], 'profile name: ' . $name);
});use FastD\Http\ServerRequest;
use FastD\Routing\RouteCollection;
use Zend\Diactoros\Response;
$collection = new RouteCollection();
$collection->group('/api/v1', function (RouteCollection $collection) {
$collection->addRoute('GET', '/users', function (ServerRequest $request, $handler) {
return new Response(200, [], 'api v1 users');
});
$collection->addRoute('GET', '/posts', function (ServerRequest $request, $handler) {
return new Response(200, [], 'api v1 posts');
});
});
$route = $collection->match(new ServerRequest('GET', '/api/v1/users'));use FastD\Http\ServerRequest;
use FastD\Routing\RouteCollection;
use FastD\Routing\RouteDispatcher;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Zend\Diactoros\Response;
// 自定义中间件
class ExampleMiddleware implements MiddlewareInterface
{
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
// 在处理前执行的操作
$request = $request->withAttribute('timestamp', time());
// 继续执行下一个中间件或路由处理器
$response = $handler->handle($request);
// 在处理后执行的操作
return $response->withHeader('X-Middleware', 'processed');
}
}
$collection = new RouteCollection();
$collection->addRoute('GET', '/middleware', function (ServerRequest $request, $handler) {
return new Response(200, [], 'middleware example');
}, [
ExampleMiddleware::class
]);
$dispatcher = new RouteDispatcher($collection);
$response = $dispatcher->dispatch(new ServerRequest('GET', '/middleware'));
echo $response->getBody();use FastD\Http\ServerRequest;
use FastD\Routing\RouteCollection;
use FastD\Routing\RouteDispatcher;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Zend\Diactoros\Response;
// 定义多个中间件类
abstract class BaseNumberMiddleware implements MiddlewareInterface
{
abstract protected function getMiddlewareName(): string;
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$number = $request->getAttribute('number') ?? 0;
$number += 1; // 每个中间件将数字加1
$processedHistory = $request->getAttribute('processed_history', []);
$processedHistory[] = [
'middleware' => $this->getMiddlewareName(),
'value' => $number
];
$request = $request->withAttribute('number', $number)
->withAttribute('processed_history', $processedHistory);
return $handler->handle($request);
}
}
class NumberIncrementMiddleware1 extends BaseNumberMiddleware
{
protected function getMiddlewareName(): string
{
return self::class;
}
}
class NumberIncrementMiddleware2 extends BaseNumberMiddleware
{
protected function getMiddlewareName(): string
{
return self::class;
}
}
class NumberIncrementMiddleware3 extends BaseNumberMiddleware
{
protected function getMiddlewareName(): string
{
return self::class;
}
}
$collection = new RouteCollection();
$collection->addRoute('GET', '/process/{number:[0-9]+}', function (ServerRequest $request, $handler) {
$finalValue = $request->getAttribute('number');
$processedHistory = $request->getAttribute('processed_history', []);
$data = [
'original_number' => $request->getAttribute('number') - count($processedHistory),
'final_number' => (int)$finalValue,
'processed_by' => $processedHistory,
'message' => 'Processing completed successfully'
];
$json = json_encode($data, JSON_PRETTY_PRINT);
return new Response(200, ['Content-Type' => 'application/json'], $json);
}, [
NumberIncrementMiddleware1::class,
NumberIncrementMiddleware2::class,
NumberIncrementMiddleware3::class
]);
$dispatcher = new RouteDispatcher($collection);
$response = $dispatcher->dispatch(new ServerRequest('GET', '/process/5'));
echo $response->getBody();
// 输出: 原始数字5,经过3个中间件处理后变成8,同时显示每个中间件的处理过程更多详细文档请参阅:
运行单元测试:
phpunit
欢迎提交 Issue 和 Pull Request 来帮助改进此项目!
MIT License