mini4work / webserver
A PHP-only process-based application server
Requires
- php: ^8.4
- ext-pcntl: *
- ext-posix: *
- ext-sockets: *
Requires (Dev)
- laravel/pint: ^1.32
- pestphp/pest: ^5.3
- phpstan/phpstan: ^2.3
Suggests
- ext-curl: Required for the built-in ACME/Let's Encrypt client
- ext-ffi: Required for HTTP/2 HPACK and the optional HTTP/3 native backends
- ext-openssl: Required for TLS and certificate generation
Provides
None
Conflicts
None
Replaces
None
README
Mini4Work is a PHP application server for HTTP/1.1, HTTP/2 and HTTP/3. It runs application handlers in worker processes and provides streaming requests and responses, TLS certificate management, worker rotation and endpoint limits.
Composer package: mini4work/webserver.
First stable release: 1.0.0.
Requirements
- PHP 8.4 or later on a supported Unix platform, with
pcntl,posixandsockets. - OpenSSL for HTTPS and cURL for managed ACME certificates.
- Enabled PHP FFI and libnghttp2 for HTTP/2.
- A supported native QUIC backend for HTTP/3.
Use a maintained, patched PHP release. Plain HTTP/1.1 does not require FFI or native protocol libraries.
Quick start
composer install
php examples/server.php
curl http://127.0.0.1:8080/
The default is local HTTP/1.1 on 127.0.0.1:8080, without TLS. The server accepts
one optional argument: a JSON configuration file.
php examples/server.php config/local-https.json
php examples/server.php config/production.json
Profiles inherit the defaults in config/local.json. Configuration paths are
relative to the selected file. See configuration.
Application handlers
Applications implement RequestHandlerInterface or use CallbackRequestHandler.
Handlers receive an explicit request and return a response:
use M4W\WebServer\Cli\ServerCommand;
use M4W\WebServer\Http\CallbackRequestHandler;
use M4W\WebServer\Http\Request;
use M4W\WebServer\Http\Response;
require __DIR__.'/vendor/autoload.php';
$handler = new CallbackRequestHandler(
static fn (Request $request): Response => Response::json([
'method' => $request->method,
'uri' => $request->uri,
])
);
exit((new ServerCommand)->run($argv ?? [__FILE__], $handler));
Read small bodies with an explicit limit, or stream larger bodies in chunks.
Multipart forms and uploads are available through $request->multipart().
See the streaming API.
Workers are long-lived. Supported request globals and native session identity are scoped across managed request switches; see request state for the boundaries and session behavior. Use request-local application state. Blocking operations block their worker. This API does not emulate PHP's full per-request SAPI lifecycle. See framework integration.
Protocols and TLS
HTTP configurations
├── HTTP/1.1 — plain TCP
├── HTTP/1.1 + TLS
├── HTTP/2 + TLS — libnghttp2 (HPACK)
└── HTTP/3 + TLS — QUIC
├── quiche
└── ngtcp2 + nghttp3
Automatic selection prefers HTTP/3, then HTTP/2, then HTTP/1.1 when their requirements are met. Explicit protocol selection requires its dependencies. TLS can use local development certificates, certificate files, or Let's Encrypt.
For HTTP/3 containers, publish both TCP and UDP. Configure the public UDP port when port mappings differ. Client HTTP/3 support and certificate trust are separate from the server's installed libraries.
Operations
Workers support bounded graceful shutdown and rotation. An optional local Unix socket provides status, worker restart and stop commands:
php examples/server.php config/managed-local.json
php examples/control.php /tmp/mini4work.sock status
php examples/control.php /tmp/mini4work.sock restart-workers
Expensive routes can have per-worker rate and concurrency limits:
php examples/server.php config/protected-local.json
See endpoint limits and capacity and overload.
Documentation
The documentation index covers configuration, application APIs, protocol installation and operational behavior. See Change Notes for release changes, fixes and known problems.
Tests
composer test
composer test:unit
composer test:security
Tests are grouped under tests/Http1, tests/Http2, tests/Http3 and
tests/Common. Shared infrastructure and scenarios covering multiple protocols
belong to Common. Unit, integration, security and interoperability tests remain
separate within each group. For example:
vendor/bin/pest --group=http2 --exclude-group=interop
vendor/bin/pest --group=http3 --exclude-group=interop
Tests require the project development dependencies and the native libraries for the protocols being exercised. Native callback regression fixtures also require a C compiler; the supplied validation Dockerfile includes one. A failing security regression is a release blocker; it must be investigated rather than skipped to obtain a passing result.