Skip to content

nexphant/server ​

Low-level HTTP socket server, request/response primitives, and high-performance router.

Install ​

bash
composer require nexphant/server

HTTP Server ​

Instantiate HttpServer with a configuration array and pass it a Router:

php
use Nexphant\Server\HttpServer;
use Nexphant\Server\Router;

$router = new Router();
$router->get('/', function ($request, $response) {
    $response->json(['ok' => true]);
});

$server = new HttpServer([
    'host' => '0.0.0.0',
    'port' => 8080,
    'max_connections' => 500,
]);

$server->handle($router);
$server->start();

Common server configuration keys:

KeyDescription
host, portBind address.
max_connections, backlogSocket capacity and listen backlog.
keep_alive_timeout, max_requestsKeep-alive behavior.
runtime_safety, performance_modeDispatch and safety mode.
event_loop, socket_driverRuntime backend selection.
max_accept_per_tick, max_read_callbacks_per_tick, max_write_callbacks_per_tick, max_deferred_per_tickEvent-loop fairness controls.
graceful_shutdown_timeoutDrain timeout on shutdown.
websocket_*, sse_*WebSocket and SSE timeout, bus, Redis, replay, and backpressure settings.

Routing & Parameters ​

Register handlers on Router for different HTTP methods. Parameters are injected into the $request attributes and passed as the third argument:

php
use Nexphant\Server\Router;

$router = new Router();

// Route with placeholder parameter
$router->get('/users/{id}', function ($request, $response, $params) {
    $userId = $params['id'] ?? null;
    $response->json(['user_id' => $userId]);
});

// Route groups
$router->group('/api', function (Router $r) {
    $r->get('/health', function ($request, $response) {
        $response->json(['status' => 'ok']);
    });
});

Middleware ​

Add middleware to the server pipeline. Middleware receives $request, $response, and route $params:

php
use Nexphant\Server\Middleware\Cors;
use Nexphant\Server\Middleware\RateLimit;

// Global middleware
$server->use(new Cors());
$server->use(new RateLimit(max: 100, window: 60));

Request & Response API ​

Handlers write responses directly by modifying the passed $response object:

php
use Nexphant\Server\Request;
use Nexphant\Server\Response;

$router->post('/echo', function (Request $req, Response $res) {
    // Read parsed JSON payload
    $body = $req->json();
    
    // Write JSON response
    $res->json($body, status: 200);
});

Common $response methods:

  • status(int $code): Set status code.
  • header(string $name, string $value): Set header.
  • body(string $body): Set response text body.
  • json(mixed $data, int $status = 200): Format and send response as JSON.

Common $request methods:

MethodDescription
header(string $name, ?string $default = null)Read a normalized request header.
query(string $name, mixed $default = null)Read query string values lazily.
post(string $name, mixed $default = null)Read JSON or form body values.
cookie(string $name, ?string $default = null)Read cookies lazily.
input(string $name, mixed $default = null)Read body first, then query values.
all()Merge query and parsed body values.
json()Return parsed JSON body.
isJson()Check JSON content type.
isMethod(string $method)Compare request method.
setAttribute, getAttribute, getAttributesStore route and middleware attributes.

Additional $response helpers:

MethodDescription
headers(array $headers)Set multiple headers.
cookie(string $name, string $value, array $options = [])Queue Set-Cookie.
html(string $html, int $status = 200)Send HTML.
text(string $text, int $status = 200)Send text.
redirect(string $url, int $status = 302)Send redirect.
notFound(string $message = 'Not Found')Send JSON 404.
error(string $message, int $status = 500)Send JSON error.
rawHttp(string $response)Send a prebuilt HTTP response.

Serve Static Files ​

Configure serving directory for assets:

php
$server->use(new StaticFiles(base_path('public'), [
    'max_age' => 86400,
    'etag' => true,
    'mime_types' => ['wasm' => 'application/wasm'],
]));

StaticFiles handles GET and HEAD, rejects traversal attempts, serves index.html for directories, and emits ETag, Last-Modified, Cache-Control, and Content-Type headers.

Fast Responses ​

Register static hot-path responses directly on HttpServer:

php
$server->fastJson('GET', '/health', ['status' => 'ok']);
$server->fastText('GET', '/robots.txt', "User-agent: *\nAllow: /\n");
$server->fastRaw('GET', '/raw', $rawHttpResponse);
$server->fastCachedJson('GET', '/stats', fn () => ['uptime' => time()], ttl: 1);

Fast routes bypass normal route dispatch for fixed paths. They are best for simple endpoints that return the same small payload often:

MethodUse Case
fastJson()Health, readiness, version, and feature metadata.
fastText()Plain text assets such as robots.txt or lightweight probes.
fastRaw()Prebuilt HTTP responses.
fastCachedJson()Dynamic JSON that can be cached for a short TTL.

Use normal router methods for paths with placeholders, request body parsing, per-route middleware, or controller dispatch.

Use RawResponseBuilder when a handler needs to return a prebuilt response:

php
use Nexphant\Server\RawResponse;
use Nexphant\Server\RawResponseBuilder;

return new RawResponse(RawResponseBuilder::json(200, ['ok' => true]));

WebSocket and SSE ​

php
$server->onWebSocket('/chat',
    onMessage: fn ($conn, string $message) => $server->sendWebSocket($conn, $message),
    onOpen: fn ($conn) => $server->joinWebSocketRoom($conn, 'general'),
    onClose: fn ($conn) => null,
);

$server->broadcastWebSocket('/chat', 'hello');
$server->broadcastWebSocketRoom('/chat', 'general', 'hello');

For Server-Sent Events, start a stream from a request handler and broadcast later:

php
$server->startSse($request, $response, $request->getConnection());
$server->sendSse($connection, ['ping' => time()], event: 'ping');
$server->broadcastSse('/events', ['message' => 'updated']);

Runtime Stats ​

php
$stats = $server->getStats();
$prometheus = $server->getMetricsText();
$server->gracefulShutdown();

Released under the MIT License.