0. 准备
新建 /path/to/your/project 目录,在此目录中创建 composer.json 并写入以下内容:
{
"require": {
"psr/http-server-handler": "^1.0",
"psr/http-server-middleware": "^1.0",
"slim/psr7": "^1.4"
},
"autoload": {
"psr-4": {
"psr15\\": "psr-15/"
}
}
}
其中,slim/psr7 是 psr/http-message 接口的一个实现,你也可以使用其他实现。
在此目录中执行
composer install
1. 请求处理调用
文件位置:/path/to/your/project/psr-15/index.php
use psr15\Handler;
use psr15\middleware\Bar;
use psr15\middleware\Foo;
use Slim\Psr7\Factory\ServerRequestFactory;
require __DIR__ . "/../vendor/autoload.php";
$queue[] = new Bar();
$queue[] = new Foo();
$handle = new Handler($queue);
$request = ServerRequestFactory::createFromGlobals();
$response = $handle->handle($request);
foreach ($response->getHeaders() as $name => $values) {
foreach ($values as $value) {
header(sprintf('%s: %s', $name, $value), false);
}
}
echo $response->getBody();
2. 请求处理类
文件位置:/path/to/your/project/psr-15/Handler.php
namespace psr15;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Slim\Psr7\Headers;
use Slim\Psr7\Response;
class Handler implements RequestHandlerInterface
{
/** var RequestHandlerInterface[] */
protected $queue;
public function __construct($queue)
{
$this->queue = $queue;
}
public function handle(ServerRequestInterface $request): ResponseInterface
{
$middleware = current($this->queue);
if ($middleware === false) {
return $this->generateResponse($request);
}
next($this->queue);
return $middleware->process($request, $this);
}
/** 生成响应对象;可以在此处调度路由,让路由返回响应对象 */
public function generateResponse(ServerRequestInterface $request): ResponseInterface
{
echo 'generate response', PHP_EOL;
$response = new Response(200, new Headers(['Content-Type' => 'text/plain']));
$response->getBody()->write('This content is from Response object');
return $response;
}
}
3. 中间件类
下面是两个中间件。
文件位置:/path/to/your/project/psr-15/middleware/Bar.php
namespace psr15\middleware;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
class Bar implements MiddlewareInterface
{
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
echo 'Before Bar', PHP_EOL;
$response = $handler->handle($request);
echo 'After Bar', PHP_EOL;
return $response;
}
}
文件位置:/path/to/your/project/psr-15/middleware/Foo.php
namespace psr15\middleware;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
class Foo implements MiddlewareInterface
{
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
echo 'Before Foo', PHP_EOL;
$response = $handler->handle($request);
echo 'After Foo', PHP_EOL;
return $response;
}
}
4. 执行
在 /path/to/your/project 目录中,执行 php -S localhost:8000 ./psr-15/index.php,在浏览器中打开 localhost:8000,可以看到输出以下内容
Before Bar
Before Foo
generate response
After Foo
After Bar
This content is from Response object
5. 参考文献
https://www.php-fig.org/psr/psr-15/
https://www.php-fig.org/psr/psr-15/meta/
https://www.slimframework.com/
https://relayphp.com/