Important
This is a baby project and may not be production ready.
Swoole micro-framework for fast concurrent applications
You can install Swoldier via Composer:
composer require wilaak/swoldierSince it relies on Swoole, make sure you have the Swoole extension installed.
pecl install swooleBelow is a usage example to get your started.
use Swoldier\{BatchLogger, HttpContext, Router};
use Swoldier\Middleware\{
RequestLogger,
BrotliCompression,
ConnectionLimiter,
RateLimiter,
};
// Create Swoole HTTP server
$server = new Swoole\Http\Server('0.0.0.0', 8082, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL);
// Server settings
$server->set([
'ssl_cert_file' => __DIR__ . '/cert.pem', // Path to SSL certificate file
'ssl_key_file' => __DIR__ . '/key.pem', // Path to SSL key file
'open_http2_protocol' => true, // Enable HTTP/2
'worker_num' => 1, // Number of worker processes
'max_wait_time' => 0, // Graceful shutdown time
]);
// Replace blocking PHP functions with coroutine-friendly versions
Swoole\Runtime::enableCoroutine();
// Create logger instance
$logger = new BatchLogger();
// Create router instance
$router = new Router($server);
// Use connection limiter middleware
$connectionLimiter = new ConnectionLimiter(
maxConnections: 100,
logger: $logger
);
$router->use($connectionLimiter);
// Use rate limiter middleware
$rateLimiter = new RateLimiter(
maxRequests: 100,
timeWindow: 60,
logger: $logger
);
$router->use($rateLimiter);
// Use request logging middleware
$requestLogger = new RequestLogger($logger);
$router->use($requestLogger);
// Use Brotli compression middleware
$brotliCompression = new BrotliCompression();
$router->use($brotliCompression);
// Serve files from the "public" directory
$router->map('GET', '/public/:file+', function (HttpContext $ctx) {
$file = $ctx->getRouteParam('file');
$ctx->file(__DIR__ . '/public/', $file);
});
// Simple route that says hello
$router->map('GET', '/', function (HttpContext $ctx) {
$ctx->html('<h1>Hello, World!</h1>');
});
// SSE endpoint that sends current time every second
$router->map('GET', '/test', function (HttpContext $ctx) {
while ($ctx->isConnected()) {
$ctx->write("data: " . date('Y-m-d H:i:s') . "\n\n");
sleep(1);
}
});
// Fallback route for custom 404 handler
$router->map('*', '/:fallback+', function (HttpContext $ctx) {
$ctx->text('404 Not Found', 404);
});
// Log server start event
$server->on('Start', function () use ($logger) {
$logger->info("Server started");
});
// Start the server
$server->start();The map method allows you to define routes for different HTTP methods and patterns.
// Simple GET route
$router->map('GET', '/hello', fn($ctx) => /* ... */);
// Multiple methods for a single route
$router->map(['GET', 'POST'], '/form', fn($ctx) => /* ... */);
// Route for all methods
$router->map('*', '/catcher', fn($ctx) => /* ... */);
// Required parameter
$router->map('GET', '/users/:id', fn($ctx) => /* ... */);
// Example requests:
// /users -> no match
// /users/123 -> ['id' => '123']
// Optional parameters
$router->map('GET', '/archive/:year?/:month?', fn($ctx) => /* ... */);
// Example requests:
// /archive -> [] (no parameters)
// /archive/1974 -> ['year' => '1974']
// /archive/1974/06 -> ['year' => '1974', 'month' => '06']
// Wildcard parameter (one or more segments)
$router->map('GET', '/files/:path+', fn($ctx) => /* ... */);
// Example requests:
// /assets -> no match
// /assets/logo.png -> ['resource' => 'logo.png']
// /assets/img/banner.jpg -> ['resource' => 'img/banner.jpg']
// Wildcard parameter (zero or more segments)
$router->map('GET', '/files/:path*', fn($ctx) => /* ... */);
// Example requests:
// /downloads -> ['file' => ''] (empty string)
// /downloads/report.pdf -> ['file' => 'report.pdf']
// /downloads/docs/guide.md -> ['file' => 'docs/guide.md']The use method allows you to register a global middleware that will be executed for every incoming request.
use Swoldier\Middleware\RequestLogger;
$requestLogger = new RequestLogger($logger);
$router->use($requestLogger);The group method allows you to create a group of routes that share the same middleware.
use Swoldier\HttpContext;
$middleware = function (HttpContext $ctx, callable $next) {
$next($ctx);
};
$group = $router->group($middleware);
$group->map('GET', '/grouped', function (HttpContext $ctx) {
// ...
});The following compression middlewares are available to compress HTTP responses.
To enable Brotli compression for responses, you can use the included BrotliCompression middleware.
Note
Brotli compression requires the brotli PHP extension to be installed and enabled. See Brotli PHP Extension.
use Swoldier\Middleware\BrotliCompression;
$brotliCompression = new BrotliCompression(
level: 4, // Compression level (0-11)
);
$router->use($brotliCompression);To enable Zstd compression for responses, you can use the included ZstdCompression middleware.
This is significantly faster than Brotli while providing comparable compression ratios. But it is not as widely supported by browsers.
Note
Zstd compression requires the zstd PHP extension to be installed and enabled. See Zstd PHP Extension.
use Swoldier\Middleware\ZstdCompression;
$zstdCompression = new ZstdCompression(
level: 3, // Compression level (1-22)
);
$router->use($zstdCompression);Some links you might find useful: