Skip to main content

Overview

The Response class provides a fluent interface for creating and sending HTTP responses with proper status codes, headers, and content formatting.

Constructor

Create a new Response instance.
public function __construct(mixed $content = '', int $statusCode = 200, array $headers = [])
content
mixed
default:""
Response content (string, array, or any value convertible to string)
statusCode
int
default:"200"
HTTP status code
headers
array
default:"[]"
Associative array of HTTP headers

Example

use Lyger\Http\Response;

$response = new Response('Hello World', 200, [
    'Content-Type' => 'text/plain'
]);

Static Factory Methods

json

Create a JSON response.
public static function json(mixed $data, int $statusCode = 200): self
data
mixed
required
Data to encode as JSON (typically an array)
statusCode
int
default:"200"
HTTP status code

Returns

response
Response
Response with Content-Type set to application/json
JSON encoding uses JSON_UNESCAPED_UNICODE and JSON_UNESCAPED_SLASHES flags for clean output.

Example

return Response::json([
    'success' => true,
    'message' => 'User created'
]);
// Content-Type: application/json
// {"success":true,"message":"User created"}

html

Create an HTML response.
public static function html(string $html, int $statusCode = 200): self
html
string
required
HTML content
statusCode
int
default:"200"
HTTP status code

Returns

response
Response
Response with Content-Type set to text/html

Example

return Response::html('
    <!DOCTYPE html>
    <html>
    <head>
        <title>Welcome</title>
    </head>
    <body>
        <h1>Welcome to Lyger</h1>
        <p>The fastest PHP framework</p>
    </body>
    </html>
');

text

Create a plain text response.
public static function text(string $text, int $statusCode = 200): self
text
string
required
Plain text content
statusCode
int
default:"200"
HTTP status code

Returns

response
Response
Response with Content-Type set to text/plain

Example

return Response::text('Plain text response');
// Content-Type: text/plain

return Response::text('Server is healthy', 200);

error

Create an error response with JSON format.
public static function error(string $message, int $statusCode = 500): self
message
string
required
Error message
statusCode
int
default:"500"
HTTP error status code

Returns

response
Response
JSON response with error message

Example

return Response::error('User not found', 404);
// {"error":"User not found"}

Instance Methods

send

Send the response to the client (outputs headers and content).
public function send(): void

Example

$response = Response::json(['status' => 'ok']);
$response->send();
// Outputs HTTP headers and JSON content

setHeader

Set a custom HTTP header.
public function setHeader(string $key, string $value): self
key
string
required
Header name
value
string
required
Header value

Returns

response
Response
Same Response instance for method chaining

Example

return Response::json(['data' => 'value'])
    ->setHeader('X-API-Version', '1.0')
    ->setHeader('X-Rate-Limit', '1000');

getHeader

Get a header value from the response.
public function getHeader(string $key, ?string $default = null): ?string
key
string
required
Header name
default
string|null
default:"null"
Default value if header doesn’t exist

Returns

value
string|null
Header value or default

Example

$response = Response::json(['data' => 'value'])
    ->setHeader('X-Custom', 'value');

$custom = $response->getHeader('X-Custom'); // "value"
$missing = $response->getHeader('X-Missing', 'default'); // "default"

getStatusCode

Get the HTTP status code.
public function getStatusCode(): int

Returns

statusCode
int
HTTP status code

Example

$response = Response::json(['data' => 'value'], 201);
$code = $response->getStatusCode(); // 201

getContent

Get the response content as a string.
public function getContent(): string

Returns

content
string
Response content

Example

$response = Response::json(['name' => 'John']);
$content = $response->getContent();
// '{"name":"John"}'

HTTP Status Codes

Common status codes to use with Response methods:

Success (2xx)

// 200 OK - Standard success response
Response::json(['data' => 'value'], 200);

// 201 Created - Resource successfully created
Response::json(['id' => 123], 201);

// 204 No Content - Success with no response body
Response::text('', 204);

Client Errors (4xx)

// 400 Bad Request - Invalid input
Response::error('Invalid request data', 400);

// 401 Unauthorized - Authentication required
Response::error('Authentication required', 401);

// 403 Forbidden - Authenticated but not authorized
Response::error('Access denied', 403);

// 404 Not Found - Resource doesn't exist
Response::error('User not found', 404);

// 422 Unprocessable Entity - Validation failed
Response::error('Validation failed', 422);

Server Errors (5xx)

// 500 Internal Server Error - Generic server error
Response::error('Internal server error', 500);

// 503 Service Unavailable - Service temporarily down
Response::error('Service unavailable', 503);

Custom Headers

CORS Headers

return Response::json(['data' => 'value'])
    ->setHeader('Access-Control-Allow-Origin', '*')
    ->setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE')
    ->setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');

Cache Control

return Response::json(['data' => 'value'])
    ->setHeader('Cache-Control', 'public, max-age=3600')
    ->setHeader('Expires', gmdate('D, d M Y H:i:s', time() + 3600) . ' GMT');

Custom API Headers

return Response::json(['users' => $users])
    ->setHeader('X-Total-Count', (string) count($users))
    ->setHeader('X-Page', '1')
    ->setHeader('X-Per-Page', '10');

Response Patterns

RESTful API Responses

use Lyger\Http\Request;
use Lyger\Http\Response;

// List resources
Route::get('/api/users', function(Request $request) {
    return Response::json([
        'data' => [
            ['id' => 1, 'name' => 'John'],
            ['id' => 2, 'name' => 'Jane']
        ]
    ]);
});

// Create resource
Route::post('/api/users', function(Request $request) {
    $data = $request->all();
    
    return Response::json([
        'id' => 123,
        'name' => $data['name']
    ], 201);
});

// Update resource
Route::put('/api/users/{id}', function(Request $request, $id) {
    return Response::json([
        'id' => $id,
        'updated' => true
    ]);
});

// Delete resource
Route::delete('/api/users/{id}', function(Request $request, $id) {
    return Response::text('', 204);
});

Error Handling

Route::get('/api/users/{id}', function(Request $request, $id) {
    if (!is_numeric($id)) {
        return Response::error('Invalid user ID', 400);
    }
    
    $user = findUser($id);
    
    if (!$user) {
        return Response::error('User not found', 404);
    }
    
    return Response::json(['user' => $user]);
});

Conditional Responses

Route::get('/api/data', function(Request $request) {
    $format = $request->get('format', 'json');
    
    $data = ['name' => 'John', 'age' => 30];
    
    return match($format) {
        'json' => Response::json($data),
        'text' => Response::text(json_encode($data)),
        'html' => Response::html("<pre>" . json_encode($data, JSON_PRETTY_PRINT) . "</pre>"),
        default => Response::error('Invalid format', 400)
    };
});

Paginated Responses

Route::get('/api/posts', function(Request $request) {
    $page = (int) $request->get('page', 1);
    $perPage = 10;
    
    // Fetch posts...
    $posts = [];
    $total = 100;
    
    return Response::json([
        'data' => $posts,
        'meta' => [
            'current_page' => $page,
            'per_page' => $perPage,
            'total' => $total,
            'last_page' => ceil($total / $perPage)
        ]
    ])->setHeader('X-Total-Count', (string) $total);
});

Complete Example

use Lyger\Http\Request;
use Lyger\Http\Response;
use Lyger\Routing\Route;

// Homepage
Route::get('/', function(Request $request) {
    return Response::html('
        <!DOCTYPE html>
        <html>
        <head><title>Lyger API</title></head>
        <body>
            <h1>Welcome to Lyger API</h1>
            <p>Visit /api/users for the API</p>
        </body>
        </html>
    ');
});

// API endpoint with validation
Route::post('/api/users', function(Request $request) {
    $name = $request->input('name');
    $email = $request->input('email');
    
    // Validate input
    if (!$name || !$email) {
        return Response::error('Name and email are required', 400);
    }
    
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        return Response::error('Invalid email format', 422);
    }
    
    // Check authentication
    $apiKey = $request->header('X-API-Key');
    if ($apiKey !== 'secret-key') {
        return Response::error('Unauthorized', 401);
    }
    
    // Create user
    $user = [
        'id' => rand(1000, 9999),
        'name' => $name,
        'email' => $email,
        'created_at' => date('Y-m-d H:i:s')
    ];
    
    // Return with custom headers
    return Response::json([
        'success' => true,
        'user' => $user
    ], 201)
        ->setHeader('X-API-Version', '1.0')
        ->setHeader('X-Request-ID', uniqid());
});

// Health check endpoint
Route::get('/health', function(Request $request) {
    return Response::json([
        'status' => 'healthy',
        'timestamp' => time()
    ])->setHeader('Cache-Control', 'no-cache');
});

// Download endpoint
Route::get('/download', function(Request $request) {
    return Response::text('File contents here')
        ->setHeader('Content-Disposition', 'attachment; filename="data.txt"');
});