The Response API provides comprehensive HTTP response management with modern features, security headers, content negotiation, and flexible response formatting. Built for production-ready web applications and APIs.
Location: Core/Libraries/Response.php
Access: Available as $this->response in controllers
Version: 2.0.0 with modern security features
- Complete 1xx-5xx Support: All standard HTTP status codes (100-599)
- Status Messages: Proper status text for each code
- Validation: Prevents invalid status codes
- Headers Management: Multiple header support with proper formatting
- Content Type Handling: MIME type and charset management
- Cookie Support: Secure cookie configuration
- Security Headers: Default security headers included
Sets the HTTP status code with validation.
Parameters:
$code(int): HTTP status code (100-599)
Returns: Response - For method chaining
Throws: InvalidArgumentException - For invalid status codes
Example:
// Set specific status codes
$this->response->setStatusCode(201); // Created
$this->response->setStatusCode(404); // Not Found
$this->response->setStatusCode(500); // Internal Server Error
// Method chaining
$this->response->setStatusCode(400)
->setContentType('application/json')
->sendJson(['error' => 'Bad Request']);
// API controller example
public function createUser() {
try {
$user = $this->models->user->createUser($this->request->post());
$this->response->setStatusCode(201)
->sendJson($user);
} catch (Exception $e) {
$this->response->setStatusCode(422)
->sendError('Validation failed', 422, ['details' => $e->getMessage()]);
}
}Gets the current HTTP status code.
Returns: int - Current status code
Example:
$currentStatus = $this->response->getStatusCode(); // Returns: 200 (default)
// Conditional response handling
if ($this->response->getStatusCode() >= 400) {
error_log("Error response: " . $this->response->getStatusCode());
}Alias for setStatusCode() for backward compatibility.
Parameters:
$status(int): HTTP status code
Returns: Response - For method chaining
Sets a response header with optional multi-value support.
Parameters:
$name(string): Header name$value(string): Header value$replace(bool): Whether to replace existing header
Returns: Response - For method chaining
Example:
// Basic header setting
$this->response->setHeader('Cache-Control', 'no-cache, no-store');
$this->response->setHeader('X-API-Version', '1.0');
// Multiple values for same header
$this->response->setHeader('Set-Cookie', 'session=abc123', false);
$this->response->setHeader('Set-Cookie', 'preferences=theme-dark', false);
// Security headers
$this->response->setHeader('X-Frame-Options', 'DENY');
$this->response->setHeader('Content-Security-Policy', "default-src 'self'");
// API rate limiting
public function handleApiRequest() {
$remaining = $this->getRateLimitRemaining();
$this->response->setHeader('X-RateLimit-Remaining', (string)$remaining);
if ($remaining <= 0) {
$this->response->setStatusCode(429)
->setHeader('Retry-After', '3600')
->sendError('Rate limit exceeded');
}
}Gets a response header value.
Parameters:
$name(string): Header name (case-insensitive)
Returns: string|array|null - Header value(s) or null if not set
Example:
$contentType = $this->response->getHeader('Content-Type');
$cacheControl = $this->response->getHeader('cache-control'); // Case-insensitive
// Check if header is set
if ($this->response->getHeader('X-Custom-Header')) {
// Header exists
}Removes a response header.
Parameters:
$name(string): Header name
Returns: Response - For method chaining
Example:
// Remove default security header for specific response
$this->response->removeHeader('X-Frame-Options');
// Conditional header removal
if ($this->request->isAjax()) {
$this->response->removeHeader('Cache-Control');
}Sets multiple headers at once.
Parameters:
$headers(array): Associative array of headers
Returns: Response - For method chaining
Example:
// Set multiple headers
$this->response->setHeaders([
'Cache-Control' => 'max-age=3600',
'X-API-Version' => '2.0',
'Access-Control-Allow-Origin' => '*'
]);
// API response headers
$apiHeaders = [
'X-Total-Count' => $totalUsers,
'X-Page-Number' => $page,
'X-Items-Per-Page' => $limit
];
$this->response->setHeaders($apiHeaders);Sets the content type and optional charset.
Parameters:
$contentType(string): MIME type$charset(string|null): Character encoding
Returns: Response - For method chaining
Example:
// Basic content types
$this->response->setContentType('application/json');
$this->response->setContentType('text/xml', 'UTF-8');
$this->response->setContentType('application/pdf');
// File download
public function downloadReport() {
$this->response->setContentType('application/vnd.ms-excel')
->setHeader('Content-Disposition', 'attachment; filename="report.xlsx"')
->setContent($excelData)
->send();
}Sets content type to JSON.
Returns: Response - For method chaining
Example:
$this->response->json()
->setContent(json_encode($data))
->send();
// Method chaining for API responses
$this->response->json()->sendJson($users);Sets content type to XML.
Returns: Response - For method chaining
Example:
$xmlData = $this->generateXmlFeed($posts);
$this->response->xml()
->setContent($xmlData)
->send();Sets content type to plain text.
Returns: Response - For method chaining
Example:
// Plain text response
$this->response->text()
->setContent("Server Status: OK\nUptime: 24 days")
->send();Sets content type to HTML.
Returns: Response - For method chaining
Example:
$this->response->html()
->setContent($htmlContent)
->send();Sets the response content/body.
Parameters:
$content(mixed): Response content
Returns: Response - For method chaining
Example:
// String content
$this->response->setContent('Hello, World!');
// Array content (will be JSON encoded if content type is JSON)
$this->response->json()->setContent(['message' => 'Success']);
// File content
$fileContent = file_get_contents('report.pdf');
$this->response->setContentType('application/pdf')
->setContent($fileContent);Gets the current response content.
Returns: mixed - Current response content
Example:
$currentContent = $this->response->getContent();
// Modify existing content
$content = $this->response->getContent();
$content .= "\n\nAdditional information";
$this->response->setContent($content);Appends content to the existing response.
Parameters:
$content(string): Content to append
Returns: Response - For method chaining
Example:
$this->response->setContent('Initial content');
$this->response->appendContent(' - Additional data');
$this->response->appendContent(' - More data');
// Result: "Initial content - Additional data - More data"
// Building dynamic responses
public function buildReport() {
$this->response->text()->setContent("Report Generated\n\n");
foreach ($this->getReportSections() as $section) {
$this->response->appendContent($section . "\n");
}
$this->response->send();
}setCookie($name, $value, $expires = 0, $path = '/', $domain = '', $secure = false, $httpOnly = true, $sameSite = 'Lax')
Sets a cookie with security options.
Parameters:
$name(string): Cookie name$value(string): Cookie value$expires(int): Expiration timestamp (0 = session cookie)$path(string): Cookie path$domain(string): Cookie domain$secure(bool): HTTPS only$httpOnly(bool): HTTP only (no JavaScript access)$sameSite(string): SameSite attribute ('Strict', 'Lax', 'None')
Returns: Response - For method chaining
Example:
// Session cookie
$this->response->setCookie('user_preference', 'dark_mode');
// Long-term cookie
$expires = time() + (30 * 24 * 60 * 60); // 30 days
$this->response->setCookie('remember_token', $token, $expires);
// Secure cookie for HTTPS
$this->response->setCookie('secure_data', $data, 0, '/', '', true, true, 'Strict');
// Authentication example
public function login() {
if ($this->auth->login($email, $password)) {
$token = $this->auth->generateRememberToken();
$this->response->setCookie('remember_token', $token, time() + (30 * 24 * 60 * 60));
$this->response->redirect('/dashboard');
}
}setCorsHeaders($origins = '*', $methods = ['GET', 'POST', 'PUT', 'DELETE'], $headers = [], $credentials = false, $maxAge = 3600)
Sets CORS (Cross-Origin Resource Sharing) headers.
Parameters:
$origins(string|array): Allowed origins$methods(string|array): Allowed HTTP methods$headers(string|array): Allowed headers$credentials(bool): Allow credentials$maxAge(int): Preflight cache time in seconds
Returns: Response - For method chaining
Example:
// Basic CORS for API
$this->response->setCorsHeaders('*', ['GET', 'POST'], ['Content-Type', 'Authorization']);
// Specific origins
$this->response->setCorsHeaders([
'https://myapp.com',
'https://admin.myapp.com'
], ['GET', 'POST', 'PUT', 'DELETE'], [], true);
// API endpoint with CORS
public function apiEndpoint() {
$this->response->setCorsHeaders('*', ['GET', 'POST'], ['Content-Type']);
if ($this->request->method() === 'options') {
$this->response->setStatusCode(200)->send();
return;
}
// Handle actual request
$this->response->sendJson(['data' => $apiData]);
}Sends a JSON response and exits.
Parameters:
$data(mixed): Data to encode as JSON$statusCode(int): HTTP status code$flags(int): JSON encoding flags
Returns: void - Exits after sending
Example:
// Simple JSON response
$this->response->sendJson(['message' => 'Success']);
// With status code
$this->response->sendJson(['user' => $userData], 201);
// API responses
public function getUsers() {
$users = $this->models->user->getAllUsers();
$this->response->sendJson([
'users' => $users,
'total' => count($users),
'page' => $this->request->get('page', 1)
]);
}
public function createUser() {
$userData = $this->request->post();
try {
$newUser = $this->models->user->createUser($userData);
$this->response->sendJson($newUser, 201);
} catch (Exception $e) {
$this->response->sendJson(['error' => $e->getMessage()], 400);
}
}Sends a standardized error response.
Parameters:
$message(string): Error message$statusCode(int): HTTP status code$details(array): Additional error details
Returns: void - Exits after sending
Example:
// Simple error
$this->response->sendError('User not found', 404);
// With details
$this->response->sendError('Validation failed', 422, [
'fields' => ['email' => 'Email is required', 'password' => 'Password too short']
]);
// Error handling in controller
public function updateUser() {
$userId = $this->router->param('id');
if (!$userId || !is_numeric($userId)) {
$this->response->sendError('Invalid user ID', 400);
return;
}
$user = $this->models->user->getUserById($userId);
if (!$user) {
$this->response->sendError('User not found', 404);
return;
}
// Update logic...
}Sends a standardized success response.
Parameters:
$data(mixed): Response data$message(string): Success message$statusCode(int): HTTP status code
Returns: void - Exits after sending
Example:
// Simple success
$this->response->sendSuccess();
// With data
$this->response->sendSuccess($userData, 'User created successfully', 201);
// API success responses
public function deleteUser() {
$userId = $this->router->param('id');
if ($this->models->user->deleteUser($userId)) {
$this->response->sendSuccess(null, 'User deleted successfully');
} else {
$this->response->sendError('Failed to delete user', 500);
}
}Sends a redirect response.
Parameters:
$url(string): Redirect URL$statusCode(int): HTTP status code (301, 302, 303, 307, 308)
Returns: void - Exits after sending
Example:
// Temporary redirect (302)
$this->response->redirect('/login');
// Permanent redirect (301)
$this->response->redirect('/new-url', 301);
// Post-login redirect
public function login() {
if ($this->auth->login($email, $password)) {
$redirectUrl = $_SESSION['redirect_after_login'] ?? '/dashboard';
unset($_SESSION['redirect_after_login']);
$this->response->redirect($redirectUrl);
} else {
$this->session->setFlashData('error', 'Invalid credentials');
$this->response->redirect('/login');
}
}Sends a file download response.
Parameters:
$filePath(string): Path to file$downloadName(string|null): Download filename$deleteAfter(bool): Whether to delete file after download
Returns: void - Exits after sending
Example:
// Simple file download
$this->response->download('/path/to/report.pdf');
// Custom download name
$this->response->download('/tmp/export_123.csv', 'user_export.csv');
// Temporary file download
$this->response->download('/tmp/temp_report.pdf', 'report.pdf', true);
// Generated report download
public function exportUsers() {
$this->auth->requireGroup('admin');
$users = $this->models->user->getAllUsers();
$csvContent = $this->generateCsv($users);
$tempFile = tempnam(sys_get_temp_dir(), 'users_export_');
file_put_contents($tempFile, $csvContent);
$this->response->download($tempFile, 'users_export.csv', true);
}Sends HTTP headers (called automatically by send()).
Returns: Response - For method chaining
Example:
// Manual header sending (advanced usage)
$this->response->setStatusCode(200)
->setContentType('text/plain')
->sendHeaders();
echo "Custom content output";Sends the complete response and exits.
Returns: void - Exits after sending
Example:
$this->response->setStatusCode(200)
->setContentType('text/html')
->setContent('<h1>Hello World</h1>')
->send();
// With method chaining
$this->response->html()
->setContent($htmlContent)
->send();Legacy method for backward compatibility.
Parameters:
$data(mixed): Data to output
Returns: void - Exits after sending
Example:
// Backward compatibility
$this->response->json();
$this->response->output(['message' => 'Hello']);
// Equivalent to:
$this->response->sendJson(['message' => 'Hello']);class ApiController extends Controller
{
public function before()
{
// Set CORS headers for all API endpoints
$this->response->setCorsHeaders('*', ['GET', 'POST', 'PUT', 'DELETE'], [
'Content-Type', 'Authorization'
]);
// Handle preflight requests
if ($this->request->method() === 'options') {
$this->response->setStatusCode(200)->send();
}
}
public function getUser()
{
$userId = $this->router->param('id');
if (!$userId || !is_numeric($userId)) {
$this->response->sendError('Invalid user ID', 400);
return;
}
$user = $this->models->user->getUserById($userId);
if (!$user) {
$this->response->sendError('User not found', 404);
return;
}
$this->response->sendJson($user);
}
public function createUser()
{
try {
$userData = $this->request->only(['name', 'email', 'password']);
$newUser = $this->models->user->createUser($userData);
$this->response->sendSuccess($newUser, 'User created successfully', 201);
} catch (Exception $e) {
$this->response->sendError('Failed to create user', 422, [
'details' => $e->getMessage()
]);
}
}
}class DownloadController extends Controller
{
public function report()
{
$this->auth->required();
$this->auth->requireGroup(['admin', 'manager']);
$reportId = $this->router->param('id');
$report = $this->models->report->getById($reportId);
if (!$report || !file_exists($report['file_path'])) {
$this->response->sendError('Report not found', 404);
return;
}
// Log download
$this->models->analytics->logDownload($reportId, $this->auth->user['id']);
$this->response->download($report['file_path'], $report['filename']);
}
public function generateCsv()
{
$this->auth->requireGroup('admin');
$users = $this->models->user->getAllUsers();
$csv = $this->generateUsersCsv($users);
$tempFile = tempnam(sys_get_temp_dir(), 'users_');
file_put_contents($tempFile, $csv);
$filename = 'users_export_' . date('Y-m-d') . '.csv';
$this->response->download($tempFile, $filename, true);
}
}class PostsController extends Controller
{
public function index()
{
$posts = $this->models->post->getAllPosts();
if ($this->request->wantsJson()) {
// API request
$this->response->sendJson([
'posts' => $posts,
'total' => count($posts)
]);
} else {
// Web request
$this->view->render('posts/index', ['posts' => $posts]);
}
}
public function feed()
{
$posts = $this->models->post->getRecentPosts(20);
$xml = $this->generateRssFeed($posts);
$this->response->xml()
->setHeader('Cache-Control', 'max-age=3600')
->setContent($xml)
->send();
}
}The Response class automatically sets these security headers:
X-Content-Type-Options: nosniffX-Frame-Options: DENYX-XSS-Protection: 1; mode=blockReferrer-Policy: strict-origin-when-cross-origin
httpOnly: true- Prevents JavaScript accesssameSite: 'Lax'- CSRF protection- Configurable
secureflag for HTTPS
- Flexible origin validation
- Method and header restrictions
- Credential handling
- Preflight caching
The Response API integrates seamlessly with other framework components:
- Request: Content negotiation based on Accept headers
- Authentication: Automatic error responses for unauthorized access
- Router: Parameter-based response handling
- View: Template rendering for HTML responses
- Session: Flash message integration with redirects
- Cache: Cache header management for performance
The Response API provides enterprise-level HTTP response handling with modern security features and flexible content management.