Caution
The documentation you are viewing is for an older version of this component.
Switch to the latest (v2) version.
Reference
In This Article
How it works
When you run an Expressive application using Swoole, you will execute PHP from the command line interface, without using a web server.
This sounds a bit strange in PHP, though it will be familiar to Node.js developers; the execution model under Swoole is similar to that technology.
The HTTP server of Swoole is a PHP class that offers callbacks on a number of events,
using the on(string $name, callable $action)
method.
The request handler implemented in zend-expressive-swoole is a runner that
enables the execution of an Expressive application inside the on('request')
event of Swoole\Http\Server
. This runner is implemented in the
Zend\Expressive\Swoole\SwooleRequestHandlerRunner
class.
The basic implementation looks similar to the following:
public function run() : void
{
$this->swooleHttpServer->on('start', function ($server) {
printf("Swoole is running at %s:%s\n", $server->host, $server->port);
});
$this->swooleHttpServer->on('request', function ($request, $response) {
printf(
"%s - %s - %s %s\n",
date('Y-m-d H:i:sO', time()),
$request->server['remote_addr'],
$request->server['request_method'],
$request->server['request_uri']
);
$emitter = new SwooleEmitter($response);
try {
$psr7Request = ($this->serverRequestFactory)($request);
} catch (Throwable $e) {
// Error in generating the request
$this->emitMarshalServerRequestException($emitter, $e);
return;
}
$emitter->emit($this->handler->handle($psr7Request));
});
$this->swooleHttpServer->start();
}
This package provides a bridge between Swoole\Http\Request
($request
) and
PSR-7 requests ($psr7Request
;
specifically as implemented by zend-diactoros)
via the class Zend\Expressive\Swoole\ServerRequestSwooleFactory
.
It also provides a Swoole-specific emitter, Zend\Expressive\Swoole\SwooleEmitter
,
that converts a PSR-7 response to a Swoole\Http\Response
instance.
When you run an Expressive application using zend-expressive-swoole, you will notice a bunch of PHP processes running. By default, Swoole executes 4 worker (or reactor) processes and 1 master process, for a total of 5 PHP processes.
The advantages of this architecture are many: it's very light and simple (just PHP processes running); it offers a service layer that is able to restart a worker automatically if it's not responding; and it allows executing multiple HTTP requests in parallel. The architecture is built for scaling.
Performance
The ZF developers performed a benchmark running the default zend-expressive-skeleton application with Swoole 4.0.1, nginx 1.12.1, and Apache 2.4.27 (with mod_php) using PHP 7.2.7.
The results demonstrated that Expressive with Swoole runs 4 to 5 times faster than nginx or Apache.
This impressive result is primarily due to the shared memory approach of Swoole. Unlike traditional apache/php-fpm usage, the memory allocated in Swoole will not be freed after a request. This allows application configuration and artifacts (such as middleware and handlers) to persist between requests and processes.
Under Swoole 4.1+, for even better performance, you can enable the option
zend-expressive-swoole.swoole-http-server.options.enable_coroutine
. When this
is enabled, Swoole will run most I/O processes in coroutines. Doing so provides
approximately 10 times faster performance than without coroutines, meaning a
Swoole-based application can be 40 to 50 times faster than running under nginx
or Apache. Performance improves with the number of workers (which are restricted
by the amount of memory); as such, performance can increase from these numbers.
Found a mistake or want to contribute to the documentation? Edit this page on GitHub!