Join 4,000+ others and never miss out on new tips, tutorials, and more.
Latest version:
pecl install openswoole-22.1.2 | composer require openswoole/core:22.1.5
Psr (PHP Standards Recommendations) is the community effort of moving PHP forward through collaboration and standards. To better support the community standards, OpenSwoole Psr is a part of OpenSwoole Core since v22 (version 2022).
You have to install OpenSwoole Core library with
composer require openswoole/core
to use this feature.
$server->handle()
and $server->setHandler()
PSR-7 defines interfaces for Request
and Response
.
OpenSwoole provides PSR-7 implementation and you can use any PSR-7 implementation.
The PSR-7 interface provides these methods to transform Request and Response objects:
Middlewares implement the PSR-15 Middleware Interface Psr\Http\Server\MiddlewareInterface
:
Psr\Http\Message\ServerRequestInterface
- PSR-7 request object
Psr\Http\Server\RequestHandlerInterface
- PSR-15 request handler
You can run codes before and after your main application and modify Request
and Response
with Middleware.
Example Middleware:
<?php
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Psr\Http\Message\ResponseInterface;
class MiddlewareA implements MiddlewareInterface
{
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$requestBody = $request->getBody();
var_dump('BEFORE');
$response = $handler->handle($request);
var_dump('AFTER');
return $response;
}
}
You can use StackHandler to add multiple Middlewares into your application.
OpenSwoole provides the built-in server request handler \OpenSwoole\Core\Psr\Middleware\StackHandler.
You can use $server->setHandler()
API to integrate with any Psr request handler implements \Psr\Http\Server\RequestHandlerInterface
.
<?php
use OpenSwoole\HTTP\Server;
$server = new Server('127.0.0.1', 9501, Server::SIMPLE_MODE);
$server->setHandler(\Psr\Http\Server\RequestHandlerInterface $handler);
$server->start();
Alternatively, you can use $server->handle()
API to handle Psr requests implementing Psr\Http\Message\RequestInterface
:
<?php
use OpenSwoole\Core\Psr\Response;
$server->handle(function ($request) {
// ...
return (new Response('Hello OpenSwoole Psr'))->withHeader('x-version', '2022');;
});
// or pass in your handler
$server->handle(function ($request) use ($handler) {
return $handler->handle($request);
});
Use FastRoute
package to implement a HTTP Psr server.
<?php
declare(strict_types=1);
use FastRoute\RouteCollector;
use OpenSwoole\Core\Psr\Middleware\StackHandler;
use OpenSwoole\Core\Psr\Response;
use OpenSwoole\HTTP\Server;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
$server = new Server('127.0.0.1', 9501, Server::SIMPLE_MODE);
$server->on('start', function (Server $server) {
echo "OpenSwoole http server is started at http://127.0.0.1:9501\n";
});
class MiddlewareA implements MiddlewareInterface
{
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$requestBody = $request->getBody();
var_dump('A1');
$response = $handler->handle($request);
var_dump('A2');
return $response;
}
}
class MiddlewareB implements MiddlewareInterface
{
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$requestBody = $request->getBody();
var_dump('B1');
$response = $handler->handle($request);
var_dump('B2');
return $response;
}
}
$dispatcher = \FastRoute\simpleDispatcher(function (RouteCollector $r) {
$r->addRoute('GET', '/hello/{name}', function ($request) {
$name = $request->getAttribute('name');
return new Response(sprintf('Hello %s', $name));
});
});
class RouteMiddleware implements MiddlewareInterface
{
private $dispatcher;
public function __construct($dispatcher)
{
$this->dispatcher = $dispatcher;
}
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$routeInfo = $this->dispatcher->dispatch($request->getMethod(), $request->getUri()->getPath());
switch ($routeInfo[0]) {
case \FastRoute\Dispatcher::NOT_FOUND:
return new Response('Not found', 404, '', ['Content-Type' => 'text/plain']);
case \FastRoute\Dispatcher::METHOD_NOT_ALLOWED:
return new Response('Method not allowed', 405, '', ['Content-Type' => 'text/plain']);
case \FastRoute\Dispatcher::FOUND:
foreach ($routeInfo[2] as $key => $value) {
$request = $request->withAttribute($key, $value);
}
return $routeInfo[1]($request);
}
}
}
$stack = (new StackHandler())
->add(new RouteMiddleware($dispatcher))
// ->add(new MiddlewareA())
// ->add(new MiddlewareB())
;
$server->setHandler($stack);
$server->start();