Framework/src/Http/Kernel.php

80 lines
2.3 KiB
PHP
Raw Normal View History

2025-12-14 23:10:01 +00:00
<?php
declare(strict_types=1);
namespace Phred\Http;
use DI\Container;
use DI\ContainerBuilder;
use FastRoute\Dispatcher;
use FastRoute\RouteCollector;
use Nyholm\Psr7\Factory\Psr17Factory;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface as ServerRequest;
use Relay\Relay;
use function FastRoute\simpleDispatcher;
/**
* Core HTTP Kernel builds container, routes, and PSR-15 pipeline and processes requests.
*/
final class Kernel
{
private Container $container;
private Dispatcher $dispatcher;
public function __construct(?Container $container = null, ?Dispatcher $dispatcher = null)
{
$this->container = $container ?? $this->buildContainer();
$this->dispatcher = $dispatcher ?? $this->buildDispatcher();
}
public function container(): Container
{
return $this->container;
}
public function dispatcher(): Dispatcher
{
return $this->dispatcher;
}
public function handle(ServerRequest $request): ResponseInterface
{
$psr17 = new Psr17Factory();
$middleware = [
new Middleware\RoutingMiddleware($this->dispatcher, $psr17),
new Middleware\DispatchMiddleware($this->container, $psr17),
];
$relay = new Relay($middleware);
return $relay->handle($request);
}
private function buildContainer(): Container
{
$builder = new ContainerBuilder();
// Add definitions/bindings here as needed.
return $builder->build();
}
private function buildDispatcher(): Dispatcher
{
$routesPath = dirname(__DIR__, 2) . '/routes';
$collector = static function (RouteCollector $r) use ($routesPath): void {
// Load user-defined routes if present
$router = new Router($r);
foreach (['web.php', 'api.php'] as $file) {
$path = $routesPath . '/' . $file;
if (is_file($path)) {
/** @noinspection PhpIncludeInspection */
(static function ($router) use ($path) { require $path; })($router);
}
}
// Ensure a default health route exists for acceptance/demo
$r->addRoute('GET', '/_phred/health', [Controllers\HealthController::class, '__invoke']);
};
return simpleDispatcher($collector);
}
}