'0.0.0.0', 'Access-Control-Allow-Methods' => 'GET, POST, PUT, PATCH, DELETE, OPTIONS', 'Access-Control-Allow-Headers' => 'Content-Type, Authorization, X-Requested-With, Accept, Origin', 'Access-Control-Allow-Credentials' => 'true', 'Access-Control-Max-Age' => '86400', // cache de preflight por 24h ]; // 2) Responde direto a preflight if ($request->getMethod() === 'OPTIONS') { return new Response(204, $corsHeaders); } // 3) Se o “next” vier como string (nome de classe), instancia‑o: if (is_string($next) && class_exists($next)) { $instance = new $next(); // se tiver __invoke, use-o if (is_callable($instance)) { $next = $instance; } // caso seu controller siga outro padrão PSR-15, adapte aqui: // elseif (method_exists($instance, 'handle')) { // $next = [$instance, 'handle']; // } else { throw new \RuntimeException("Controller “{$next}” não é callable"); } } // 4) Chama o próximo handler (agora garantidamente callable) $response = $next($request); // 5) Injeta os headers CORS na resposta foreach ($corsHeaders as $h => $v) { $response = $response->withHeader($h, $v); } return $response; } }