Skip to content
Muhammet Şafak edited this page May 24, 2026 · 1 revision

Response

InitPHP\HTTP\Message\Response is the PSR-7 response message. It implements Psr\Http\Message\ResponseInterface.

useInitPHP\HTTP\Message\Response;

Construction

$response = newResponse(
int $status = 200,
array $headers = [],
string|resource|StreamInterface|null $body = null,
string $version = '1.1',
?string $reason = null// null → IANA-canonical reason for $status
);

Examples:

// Bare 200$response = newResponse();
// 404 with a plain body$response = newResponse(404, ['Content-Type' => 'text/plain'], 'Nothing here.');
// 201 with an explicit reason override$response = newResponse(201, [], '{"id":42}', '1.1', 'Created Already');

When $reason is null and the status is in the IANA table, the canonical phrase is used: 200 → "OK", 404 → "Not Found", 500 → "Internal Server Error", etc. The full table lives in Response::PHRASES; see HTTP Status Codes.

Supported HTTP versions

The constructor validates against this allow-list:

'1.0' | '1.1' | '2' | '2.0' | '3' | '3.0'

Both '2' (PSR-7 canonical) and '2.0' are accepted; same for HTTP/3. Anything else raises InvalidArgumentException.

Reading

$response->getStatusCode(); // int$response->getReasonPhrase(); // string$response->getProtocolVersion();// "1.1"$response->getHeaders(); // array<string, string[]>$response->getHeader('X-Trace');// string[]$response->getHeaderLine('X-Trace'); // string$response->hasHeader('Content-Type'); // bool$response->getBody(); // StreamInterface

Mutating (returns a new instance)

$updated = $response
->withStatus(404)
->withStatus(418, "I'm a coffee maker, actually")
->withHeader('Content-Type', 'application/problem+json')
->withAddedHeader('Set-Cookie', 'a=1')
->withoutHeader('X-Internal')
->withBody($newStream);

withStatus() enforces the range 100..599 — anything outside raises InvalidArgumentException.

Convenience producers

json()

$response = (newResponse())->json(['ok' => true, 'data' => $rows], 200);
// Optional flags ORed into json_encode():$response = (newResponse())->json($data, 200, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);

What this does:

  • Sets Content-Type: application/json; charset=utf-8.
  • Encodes with JSON_THROW_ON_ERROR always set (plus any flags you pass). Unencodable payloads raise InvalidArgumentException instead of silently producing the literal string false.
  • Replaces the body with a fresh in-memory string-backed Stream containing the encoded JSON.
  • Returns a newResponse (clone) — original untouched.

redirect()

$response = (newResponse())->redirect('https://example.com/welcome'); // 302$response = (newResponse())->redirect('https://example.com/welcome', 301); // permanent$response = (newResponse())->redirect('https://example.com/welcome', 200, 5); // delayed

What this does:

  • Always sets Location: <uri>, so non-browser clients (HTTP libraries, crawlers, monitoring) can follow the redirect — regardless of the delay argument.
  • When $second > 0, additionally sets Refresh: <seconds>; url=<uri> so browsers honour the countdown.
  • Sets the status to the supplied code (default 302).
  • Accepts both a string URL and a Psr\Http\Message\UriInterface. Anything else raises InvalidArgumentException.
  • Returns a newResponse.

v2 → v3 note: Previously the delay branch replacedLocation with Refresh. v3 always emits Location and adds Refresh on top when a delay is supplied. See Migration Guide.

In-place mutators (rare — use inside a builder only)

Response carries set*() siblings for the with*() methods (setStatusCode, setStream, setHeader from MessageTrait, etc.) which mutate in place. They exist to make construction pleasant but are not part of the Psr\Http\Message\ResponseInterface contract — type-hinted code never sees them. See Overview & Immutability.

// Inside the same expression that constructs the response — fine.$response = (newResponse())
->setStatusCode(201)
->setHeader('Location', '/users/42');
// After the response has been handed to anything else — use with*().$audited = $response->withHeader('X-Trace-Id', $traceId);

Sending a Response to the wire

Response is a value object — it does not know how to write bytes to the HTTP server. Use the Emitter:

useInitPHP\HTTP\Emitter\Emitter;
(newEmitter())->emit($response);

See also

Clone this wiki locally