Skip to content

Commit 6a56800

Browse files
committed
Optimize documentation
1 parent f43eda3 commit 6a56800

1 file changed

Lines changed: 112 additions & 18 deletions

File tree

‎README.md‎

Lines changed: 112 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,14 @@
2121

2222
## Description
2323

24-
A request handler adapter for workerman, using PSR-7, PSR-15 and PSR-17.
24+
A request handler adapter for [workerman][6], using PSR-7, PSR-15 and PSR-17.
25+
26+
It turns a [workerman][6] HTTP `Worker` into a runtime for any [PSR-15][7] request handler: each incoming
27+
workerman request is converted into a [PSR-7][8] server request through [PSR-17][9] factories, handed to your
28+
application, and the returned PSR-7 response is sent back over the workerman connection.
29+
30+
Because workerman is a long-running process, your application is bootstrapped once per worker process and then
31+
serves many requests. This removes the per-request bootstrap cost of a classic PHP-FPM setup.
2532

2633
## Requirements
2734

@@ -32,6 +39,16 @@ A request handler adapter for workerman, using PSR-7, PSR-15 and PSR-17.
3239
* [psr/log][5]: ^2.0|^3.0.2
3340
* [workerman/workerman][6]: ^5.2.2
3441

42+
## Suggest
43+
44+
Any [PSR-7][8] / [PSR-17][9] implementation can be used, for example:
45+
46+
* [guzzlehttp/psr7][10] (with [http-interop/http-factory-guzzle][11])
47+
* [laminas/laminas-diactoros][12]
48+
* [nyholm/psr7][13]
49+
* [slim/psr7][14]
50+
* [sunrise/http-message][15]
51+
3552
## Installation
3653

3754
Through [Composer](http://getcomposer.org) as [chubbyphp/chubbyphp-workerman-request-handler][1].
@@ -40,8 +57,18 @@ Through [Composer](http://getcomposer.org) as [chubbyphp/chubbyphp-workerman-req
4057
composer require chubbyphp/chubbyphp-workerman-request-handler "^2.3"
4158
```
4259

60+
The examples below use [slim/psr7][14] as the PSR-7 / PSR-17 implementation:
61+
62+
```sh
63+
composer require slim/psr7 "^1.8"
64+
```
65+
4366
## Usage
4467

68+
### Basic server
69+
70+
Create a `server.php` and start it with `php server.php start` (add `-d` to daemonize):
71+
4572
```php
4673
<?php
4774

@@ -53,21 +80,22 @@ use Chubbyphp\WorkermanRequestHandler\OnMessage;
5380
use Chubbyphp\WorkermanRequestHandler\PsrRequestFactory;
5481
use Chubbyphp\WorkermanRequestHandler\WorkermanResponseEmitter;
5582
use Psr\Http\Server\RequestHandlerInterface;
56-
use Some\Psr17\Factory\ServerRequestFactory;
57-
use Some\Psr17\Factory\StreamFactory;
58-
use Some\Psr17\Factory\UploadedFileFactory;
83+
use Slim\Psr7\Factory\ServerRequestFactory;
84+
use Slim\Psr7\Factory\StreamFactory;
85+
use Slim\Psr7\Factory\UploadedFileFactory;
5986
use Workerman\Worker;
6087

61-
$loader = require __DIR__.'/vendor/autoload.php';
88+
require __DIR__.'/vendor/autoload.php';
6289

63-
/** @var RequestHandlerInterface $app*/
64-
$app = ...;
90+
/** @var RequestHandlerInterface $app */
91+
$app = ...; // your PSR-15 application, bootstrapped once per worker process
6592

6693
$http = new Worker('http://0.0.0.0:8080');
6794

95+
// number of worker processes, typically the number of CPU cores
6896
$http->count = 4;
6997

70-
$http->onWorkerStart = function () {
98+
$http->onWorkerStart = static function (): void {
7199
echo 'Workerman http server is started at http://0.0.0.0:8080'.PHP_EOL;
72100
};
73101

@@ -84,7 +112,44 @@ $http->onMessage = new OnMessage(
84112
Worker::runAll();
85113
```
86114

87-
### with blackfire
115+
### Components
116+
117+
The package consists of three small, replaceable parts. Each one has an interface, so you can swap in your own
118+
implementation where the defaults don't fit.
119+
120+
| Class | Interface | Responsibility |
121+
|-----------------------------|--------------------------------------|----------------------------------------------------------------------------------------------------------------|
122+
| `OnMessage` | `OnMessageInterface` | Workerman `onMessage` callback: builds the PSR-7 request, calls the PSR-15 handler and emits the response. |
123+
| `PsrRequestFactory` | `PsrRequestFactoryInterface` | Converts a workerman request into a PSR-7 server request via the given PSR-17 factories. |
124+
| `WorkermanResponseEmitter` | `WorkermanResponseEmitterInterface` | Converts a PSR-7 response into a workerman response and sends it over the connection. |
125+
126+
`PsrRequestFactory` maps the following data:
127+
128+
* method, URI and all headers
129+
* cookies, query params and the parsed body (form data)
130+
* uploaded files, including nested ones (as `UploadedFileInterface` instances)
131+
* the raw body, written to the request body stream
132+
* server params `REMOTE_ADDR` and `REMOTE_PORT` from the TCP connection
133+
134+
### Long-running process caveats
135+
136+
Workerman keeps the PHP process alive between requests, which differs from PHP-FPM:
137+
138+
* Superglobals like `$_GET`, `$_POST`, `$_SERVER` or `$_COOKIE` are not populated. Read everything from the
139+
PSR-7 request instead.
140+
* Anything you keep in static properties or in long-lived services persists across requests. Avoid request
141+
specific state in shared objects, or reset it per request.
142+
* Only `REMOTE_ADDR` and `REMOTE_PORT` are available as server params. If you run behind a reverse proxy,
143+
use a middleware such as [chubbyphp/chubbyphp-trusted-proxy][16] to resolve the client IP from headers.
144+
145+
### With Blackfire
146+
147+
`BlackfireOnMessageAdapter` wraps an `OnMessageInterface` and profiles a request whenever the
148+
`X-Blackfire-Query` header is present, for example when triggered by the Blackfire browser extension or the
149+
`blackfire curl` command. Requests without that header pass through untouched. The probe is always ended,
150+
even if the wrapped handler throws.
151+
152+
Requires the `blackfire` extension and the [blackfire/php-sdk][17] package.
88153

89154
```php
90155
<?php
@@ -94,20 +159,36 @@ declare(strict_types=1);
94159
namespace App;
95160

96161
use Blackfire\Client;
162+
use Blackfire\Profile\Configuration;
97163
use Chubbyphp\WorkermanRequestHandler\Adapter\BlackfireOnMessageAdapter;
98-
use Chubbyphp\WorkermanRequestHandler\OnMessage;
164+
use Chubbyphp\WorkermanRequestHandler\OnMessageInterface;
165+
use Psr\Log\LoggerInterface;
99166

100-
/** @var OnMessage $onMessage */
167+
/** @var OnMessageInterface $onMessage */
101168
$onMessage = ...;
102169

103-
if (extension_loaded('blackfire') {
104-
$onMessage = new BlackfireOnMessageAdapter($onMessage, new Client());
170+
/** @var LoggerInterface $logger */
171+
$logger = ...;
172+
173+
if (extension_loaded('blackfire')) {
174+
$onMessage = new BlackfireOnMessageAdapter(
175+
$onMessage,
176+
new Client(),
177+
new Configuration(), // optional, defaults to new Configuration()
178+
$logger // optional, defaults to a NullLogger; receives Blackfire client errors
179+
);
105180
}
106181

107182
$http->onMessage = $onMessage;
108183
```
109184

110-
### with newrelic
185+
### With New Relic
186+
187+
`NewRelicOnMessageAdapter` wraps an `OnMessageInterface` and starts a New Relic transaction for every request.
188+
The transaction is always ended, even if the wrapped handler throws, so each request is reported separately
189+
instead of as one endless transaction per worker process.
190+
191+
Requires the `newrelic` extension.
111192

112193
```php
113194
<?php
@@ -117,18 +198,20 @@ declare(strict_types=1);
117198
namespace App;
118199

119200
use Chubbyphp\WorkermanRequestHandler\Adapter\NewRelicOnMessageAdapter;
120-
use Chubbyphp\WorkermanRequestHandler\OnMessage;
201+
use Chubbyphp\WorkermanRequestHandler\OnMessageInterface;
121202

122-
/** @var OnMessage $onMessage */
203+
/** @var OnMessageInterface $onMessage */
123204
$onMessage = ...;
124205

125-
if (extension_loaded('newrelic') && false !== $name = ini_get('newrelic.appname')) {
126-
$onMessage = new NewRelicOnMessageAdapter($onMessage, $name);
206+
if (extension_loaded('newrelic') && false !== $appname = ini_get('newrelic.appname')) {
207+
$onMessage = new NewRelicOnMessageAdapter($onMessage, $appname);
127208
}
128209

129210
$http->onMessage = $onMessage;
130211
```
131212

213+
Both adapters implement `OnMessageInterface`, so they can be combined by nesting them.
214+
132215
## Copyright
133216

134217
2026 Dominik Zogg
@@ -139,3 +222,14 @@ $http->onMessage = $onMessage;
139222
[4]: https://packagist.org/packages/psr/http-server-handler
140223
[5]: https://packagist.org/packages/psr/log
141224
[6]: https://packagist.org/packages/workerman/workerman
225+
[7]: https://www.php-fig.org/psr/psr-15
226+
[8]: https://www.php-fig.org/psr/psr-7
227+
[9]: https://www.php-fig.org/psr/psr-17
228+
[10]: https://packagist.org/packages/guzzlehttp/psr7
229+
[11]: https://packagist.org/packages/http-interop/http-factory-guzzle
230+
[12]: https://packagist.org/packages/laminas/laminas-diactoros
231+
[13]: https://packagist.org/packages/nyholm/psr7
232+
[14]: https://packagist.org/packages/slim/psr7
233+
[15]: https://packagist.org/packages/sunrise/http-message
234+
[16]: https://packagist.org/packages/chubbyphp/chubbyphp-trusted-proxy
235+
[17]: https://packagist.org/packages/blackfire/php-sdk

0 commit comments

Comments
 (0)