<?php
namespace Framework\Middleware;
/**
* Middleware to ensure every request has a correlation ID.
*
* The correlation ID is used to trace all log entries for a single request.
* It can be passed in via X-Correlation-ID header or generated automatically.
*/
final class CorrelationMiddleware
{
/**
* Handle the request and set correlation ID.
*
* @param callable $next The next handler in the chain
*/
public function handle(callable $next): void
{
$correlationId = $this->getOrCreateCorrelationId();
// Make globally available
$_SERVER['CORRELATION_ID'] = $correlationId;
// Set response header for tracing
if (!headers_sent()) {
header("X-Correlation-ID: {$correlationId}");
}
$next();
}
/**
* Get existing correlation ID from header or generate new one.
*/
private function getOrCreateCorrelationId(): string
{
// Check for existing correlation ID in headers
if (isset($_SERVER['HTTP_X_CORRELATION_ID']) && $_SERVER['HTTP_X_CORRELATION_ID'] !== '') {
return $_SERVER['HTTP_X_CORRELATION_ID'];
}
// Generate new correlation ID
return bin2hex(random_bytes(8));
}
/**
* Get the current correlation ID.
*/
public static function getCorrelationId(): string
{
return $_SERVER['CORRELATION_ID'] ?? bin2hex(random_bytes(8));
}
}