'Internal Server Error', 'message' => $e->getMessage(), 'file' => basename($e->getFile()), 'line' => $e->getLine() ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); exit; }); /** * Set JSON response headers and output data. */ function jsonResponse(mixed $data, int $status = 200): void { header('Content-Type: application/json; charset=utf-8'); header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS'); header('Access-Control-Allow-Headers: Content-Type'); http_response_code($status); echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); exit; } /** * Return decoded JSON body from the request. */ function getRequestBody(): array { $raw = file_get_contents('php://input'); $data = json_decode($raw, true); return is_array($data) ? $data : []; } /** * Get the HTTP request method. */ function getMethod(): string { return strtoupper($_SERVER['REQUEST_METHOD'] ?? 'GET'); } /** * Handle CORS preflight. */ function handlePreflight(): void { if (getMethod() === 'OPTIONS') { header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS'); header('Access-Control-Allow-Headers: Content-Type'); http_response_code(204); exit; } }