Response

The Lightpack\Http\Response class provides a comprehensive, fluent API for generating HTTP responses in your application. It supports status codes, headers, content types, file downloads, streaming, security, caching, advanced output, and more.

An instance is automatically available via the response() helper.


Status, Type, Message, and Body


Header Management


Sending the Response

Method Chaining

All setters return $this for fluent chaining:

response()
    ->setStatus(201)
    ->setType('application/json')
    ->setHeader('X-Resource', 'created')
    ->json(['id' => 5])
    ->send();

JSON, XML, and Plain Text Responses


File Downloads and Streaming


Streaming Responses

Lightpack’s Response class provides several ways to stream data to the client in a memory-efficient, real-time manner. This is essential for large files, live data, CSV exports, and server-sent events (SSE).

1. Arbitrary Content Streaming (stream())

Use stream() to send custom output in real time, such as:

Example: Real-time progress output

response()->stream(function() {
    for ($i = 1; $i <= 10; $i++) {
        echo "Progress: $i/10\n";
        flush(); // Push output to client immediately
        sleep(1);
    }
});

Example: Server-Sent Events (SSE)

response()
    ->setHeader('Content-Type', 'text/event-stream')
    ->stream(function() {
        for ($i = 0; $i < 5; $i++) {
            echo "data: Message $i\n\n";
            ob_flush(); flush();
            sleep(2);
        }
    });

getStreamCallback():

Example: Inspecting the stream callback

$response = response()->stream(function() {
    echo 'Streaming...';
});

$callback = $response->getStreamCallback();
if (is_callable($callback)) {
    // You can inspect, wrap, or call the callback as needed
}

Notes:

2. File Streaming for Downloads (downloadStream())

Use downloadStream() for memory-efficient, chunked file downloads:

Example: Download a large file in 2MB chunks

response()->downloadStream('/path/to/huge.zip', 'backup.zip', [], 2 * 1024 * 1024);

Best Practice: Use for files larger than a few megabytes.

3. File Streaming for Inline Display (fileStream())

Use fileStream() to stream large files for direct display in the browser (e.g., videos, PDFs):

Example: Stream a video inline

response()->fileStream('/media/bigvideo.mp4');

4. CSV Streaming (streamCsv())

Use streamCsv() to efficiently export large datasets as CSV downloads:

Example: Export users as CSV

response()->streamCsv(function() {
    echo "id,name\n";
    foreach ($users as $user) {
        echo $user->id . ',' . $user->name . "\n";
    }
}, 'users.csv');

What it does:

Default filename: If you don't provide a filename, it defaults to 'export.csv'.

5. Server-Sent Events

Use sse() for real-time, one-way communication from server to client. Ideal for live updates, notifications, progress tracking, chat messages, or any scenario where the server needs to push data to the browser continuously.

Example: Live countdown

public function countdown()
{
    return response()->sse(function($stream) {
        for ($i = 10; $i >= 1; $i--) {
            $stream->push('count', ['number' => $i]);
            sleep(1);
        }
        $stream->push('done');
    });
}

What it does:

Stream object method:

$stream->push(string $event, array $data = [])

Frontend Integration:

<div id="output"></div>

<script>
const eventSource = new EventSource('/countdown');

eventSource.addEventListener('message', (e) => {
    const data = JSON.parse(e.data);

    if (data.event === 'count') {
        document.getElementById('output').textContent = data.number;
    } else if (data.event === 'done') {
        eventSource.close();
    }
});

eventSource.addEventListener('error', (e) => {
    console.error('Connection error');
    eventSource.close();
});
</script>

Event Format:

Each event is sent as:

data: {"event":"count","number":10}

The browser receives JSON with event key plus your custom data.


Working with Redirects

What is an HTTP Redirect?

An HTTP redirect tells the browser to immediately load a different URL. This is done by sending a special status code (usually 302) and a Location header in the response. Redirects are commonly used after form submissions, login/logout, or when a resource has moved.

In Lightpack, redirects are handled by the Redirect class, accessible via the redirect() helper. This provides a clear, expressive, and testable API for all common redirect scenarios.


Common Redirect Methods

redirect()->to($url)

Redirect to any absolute or relative URL.

Example: After login, send user to dashboard

public function login()
{
    // ... authentication logic ...
    return redirect()->to('/dashboard');
}
return redirect()->to('users', ['sort' => 'asc', 'status' => 'active']);
// Redirects to: /users?sort=asc&status=active

redirect()->route($name, ...$params)

Redirect to a named route, passing route parameters as needed.

Example: After profile update, redirect to profile page

public function update($userId)
{
    // ... update logic ...
    return redirect()->route('profile', ['id' => $userId]);
}

redirect()->back()

Redirect back to the previous page (using URL stored in session, or / if unavailable).

Example: After failed form validation, return user to previous page

public function save()
{
    if (! $this->validate()) {
        // ... maybe set flash message ...
        return redirect()->back();
    }
    // ...
}

redirect()->intended($default = '/')

Redirect to the "intended" URL stored in session (commonly used after login), with a fallback URL if not set.

How it works:

  1. Checks session for _intended_url (set by AuthFilter before redirecting to login)
  2. If found: Redirects to that URL and clears it from session
  3. If not found: Redirects to the $default URL (default: /)

When to use:

redirect()->intendedRoute($routeName, ...$params)

Redirect to the intended URL, or fall back to a named route instead of a URL.

// Redirect to intended URL, or user's profile named route
return redirect()->intendedRoute('profile');

How it works:

  1. Checks session for _intended_url
  2. If found: Uses intended() to redirect there
  3. If not found: Uses route() to redirect to the named route

Why use this over intended()?

redirect()->refresh()

Redirect to the current URL (refresh the page).

Example: After a POST, refresh the page to show updated data

public function post()
{
    // ... save logic ...
    return redirect()->refresh();
}

How it works:


Session Integration

Several redirect methods rely on session data:

back() - Uses _previous_url from session

// Stored automatically by framework
session()->set('_previous_url', request()->fullUrl());

intended() and intendedRoute() - Use _intended_url from session

// Set by AuthFilter or manually
session()->setIntendedUrl('/admin/settings');

// Retrieved and cleared by redirect helpers
$url = session()->getIntendedUrl();
session()->forgetIntendedUrl();

See Sessions for more details on intended URL helpers.


Common Patterns and Best Practices

Always return the redirect from your controller:

return redirect()->to('/login');

Chain additional headers or configuration:

return redirect()->to('/login')->setHeader('X-Reason', 'auth-required');

Set flash messages before redirecting:

session()->flash('success', 'Profile updated!');
return redirect()->back();

Use named routes for maintainability:

// Good - survives route changes
return redirect()->route('dashboard');

// Less ideal - breaks if URL changes
return redirect()->to('/dashboard');

Prefer intendedRoute() over intended() for authentication:

// Good - uses named route fallback
return redirect()->intendedRoute('dashboard');

// Less ideal - hardcoded URL fallback
return redirect()->intended('/dashboard');

Session requirement:

Prefer redirect() over manual headers:

// Good
return redirect()->to('/login');

// Avoid - manual header management
response()->setStatus(302)->setHeader('Location', '/login');

View Rendering


Security Headers


Caching and Last-Modified


Summary Table of Methods

Method Purpose
setStatus(int) Set HTTP status code
getStatus() Get HTTP status code
setMessage(string) Set HTTP status message
getMessage() Get HTTP status message
setType(string) Set Content-Type
getType() Get Content-Type
setHeader(name, value) Set a header
setHeaders(array) Set multiple headers
getHeaders() Get all headers
getHeader(name) Get a header value
hasHeader(name) Check if header is set
setBody(string) Set response body
getBody() Get response body
send() Send headers and body
setTestMode(bool) Prevent exit() (for tests)
json(data) Set JSON response
xml(string) Set XML response
text(string) Set plain text response
download(path, ...) Download a file
downloadStream(path, ...) Stream file download (large files)
file(path, ...) Display a file inline
fileStream(path, ...) Stream file inline (large files)
stream(callable) Stream custom output
getStreamCallback() Get stream callback
view(file, data) Render and set a template
streamCsv(callable, name) Stream CSV file for download
secure([headers]) Add security headers
cache(maxAge, [options]) Enable HTTP caching
noCache() Disable HTTP caching
setLastModified(time) Set Last-Modified header
setRedirectUrl(url) Set a logical redirect URL
getRedirectUrl() Get the logical redirect URL

Redirect Methods (via redirect() helper)

Method Purpose
to(url) Redirect to any URL
route(name, ...params) Redirect to named route
back() Redirect to previous page
intended(default) Redirect to intended URL or fallback
intendedRoute(name, ...params) Redirect to intended URL or named route
refresh() Redirect to current URL (refresh)