wp-php-toolkit / http-server
HttpServer component for WordPress.
Requires
- php: >=7.2
- wp-php-toolkit/bytestream: ^0.8
- wp-php-toolkit/data-liberation: ^0.8
- wp-php-toolkit/http-client: ^0.8
Requires (Dev)
- phpunit/phpunit: ^9.5
- dev-trunk
- v0.8.0
- v0.7.9
- v0.7.8
- v0.7.7
- v0.7.6
- v0.7.5
- v0.7.4
- v0.7.3
- v0.7.2
- v0.7.1
- v0.7.0
- v0.6.2
- v0.6.1
- v0.6.0
- v0.5.1
- v0.5.0
- v0.4.1
- v0.4.0
- v0.3.1
- v0.3.0
- v0.2.0
- v0.1.5
- v0.1.4
- v0.1.3
- v0.1.2
- v0.1.1
- v0.1.0
- 0.0.19
- 0.0.18
- 0.0.17
- 0.0.16
- v0.0.15
- v0.0.15-alpha
- 0.0.14
- 0.0.13
- 0.0.12
- 0.0.11
- v0.0.8-alpha
- 0.0.7
- v0.0.7-alpha
- 0.0.6
- v0.0.6-alpha
- v0.0.5-alpha
- v0.0.4-alpha
- v0.0.3-alpha
- v0.0.2-alpha
- v0.0.1-alpha
This package is auto-updated.
Last update: 2026-05-19 20:25:50 UTC
README
| slug | httpserver | ||
|---|---|---|---|
| title | HttpServer | ||
| install | wp-php-toolkit/http-server | ||
| see_also |
|
A minimal blocking TCP HTTP server in pure PHP. For CLI tools and tests, not for production traffic.
Why this exists
Sometimes a PHP tool needs a tiny local HTTP surface: a test fixture server, a webhook receiver during development, a CLI tool with a browser UI, or a demo endpoint for another component. Pulling in a production web framework would obscure the example and add dependencies the toolkit avoids.
The HttpServer component is intentionally small: a blocking TCP server, incoming request objects, and response writers. It is useful for local tools and tests. It is not a replacement for nginx, Apache, php-fpm, RoadRunner, Swoole, or a production application server.
Hello world on port 8080
Run on your machine: the Playground sandbox does not allow processes to bind listening TCP ports. Save this snippet locally and run php hello-server.php.
<?php require __DIR__ . '/vendor/autoload.php'; use WordPress\HttpServer\TcpServer; use WordPress\HttpServer\IncomingRequest; use WordPress\HttpServer\Response\ResponseWriteStream; $server = new TcpServer( '127.0.0.1', 8080 ); $server->set_handler( function ( IncomingRequest $request, ResponseWriteStream $response ) { $response->send_http_code( 200 ); $response->send_header( 'Content-Type', 'text/plain' ); $response->append_bytes( "Hello from " . $request->method . " " . $request->url . "\n" ); } ); $server->serve( function ( $host, $port ) { echo "Listening on http://{$host}:{$port}\n"; } );
A tiny JSON router
Run on your machine: needs a listening port. Once running, try curl localhost:8080/api/status.
Build a CLI tool with a web UI by switching on the parsed path and method.
<?php require __DIR__ . '/vendor/autoload.php'; use WordPress\HttpServer\TcpServer; use WordPress\HttpServer\IncomingRequest; use WordPress\HttpServer\Response\ResponseWriteStream; $server = new TcpServer( '127.0.0.1', 8080 ); $server->set_handler( function ( IncomingRequest $request, ResponseWriteStream $response ) { $path = $request->get_parsed_url()->pathname; if ( '/api/status' === $path ) { $response->send_http_code( 200 ); $response->send_header( 'Content-Type', 'application/json' ); $response->append_bytes( json_encode( array( 'ok' => true, 'pid' => getmypid(), 'memory' => memory_get_usage( true ), ) ) ); return; } if ( '/api/echo' === $path && 'POST' === $request->method ) { $body = ''; while ( ! $request->body_stream->reached_end_of_data() ) { $n = $request->body_stream->pull( 4096 ); if ( $n > 0 ) $body .= $request->body_stream->consume( $n ); } $response->send_http_code( 200 ); $response->send_header( 'Content-Type', 'text/plain' ); $response->append_bytes( $body ); return; } $response->send_http_code( 404 ); $response->append_bytes( "Not found\n" ); } ); $server->serve();
Buffered response with auto Content-Length
Use BufferingResponseWriter when you want the framework to compute Content-Length for you, or when the runtime is CGI-shaped and expects the full body up front. This one runs anywhere — no socket required.
<?php require '/php-toolkit/vendor/autoload.php'; use WordPress\HttpServer\Response\BufferingResponseWriter; $writer = new BufferingResponseWriter(); $writer->send_http_code( 200 ); $writer->send_header( 'Content-Type', 'text/html' ); $writer->append_bytes( '<!doctype html><title>Hi</title><h1>Hello</h1>' ); $writer->append_bytes( '<p>Buffered body, sent at the end.</p>' ); ob_start(); $writer->close_writing(); $response_body = ob_get_clean(); echo "headers before send:\n"; foreach ( $writer->get_buffered_headers() as $name => $value ) { echo "{$name}: {$value}\n"; } echo "\nbody:\n" . $response_body;
headers before send:
Content-Type: text/html
body:
<!doctype html><title>Hi</title><h1>Hello</h1><p>Buffered body, sent at the end.</p>