-
Notifications
You must be signed in to change notification settings - Fork 0
Recipe JSON Response
Muhammet Şafak edited this page May 24, 2026
·
1 revision
use InitPHP\HTTP\Message\Response;
use InitPHP\HTTP\Emitter\Emitter;
$response = (new Response())->json(['ok' => true, 'data' => $rows], 200);
(new Emitter())->emit($response);What this does:
-
json_encode(..., JSON_THROW_ON_ERROR)— unencodable payloads raiseInvalidArgumentException, never silently producefalse. -
Content-Type: application/json; charset=utf-8. - Replaces the body with a fresh in-memory string-backed
Streamcarrying the encoded JSON. - Sets the status to
$status(default 200). - Returns a clone — the original
Responseis untouched.
Pass extra flags as the third argument:
$pretty = (new Response())->json($data, 200, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);For media types like application/vnd.example+json or application/problem+json:
use InitPHP\HTTP\Message\Response;
use InitPHP\HTTP\Message\Stream;
$body = json_encode($data, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE);
$response = (new Response(200, [
'Content-Type' => 'application/vnd.example+json; charset=utf-8',
]))->withBody(new Stream($body, null));The null Stream backend is the cheapest option for short bodies — no resource allocation, just a PHP string. See Stream.
$problem = [
'type' => 'https://example.com/probs/invalid-input',
'title' => 'Invalid input',
'status' => 422,
'detail' => 'Field "email" must be a valid address.',
'instance' => '/users',
];
$response = (new Response(422, [
'Content-Type' => 'application/problem+json',
]))->withBody(new Stream(
json_encode($problem, JSON_THROW_ON_ERROR),
null
));For megabyte-class payloads, prefer streaming over json_encode in one shot — otherwise you're materialising the entire response in memory before the first byte hits the wire.
use InitPHP\HTTP\Message\Response;
use InitPHP\HTTP\Message\Stream;
use InitPHP\HTTP\Emitter\Emitter;
$body = fopen('php://temp', 'w+b');
fwrite($body, '[');
$first = true;
foreach ($pdo->query('SELECT * FROM big_table') as $row) {
if (!$first) fwrite($body, ',');
fwrite($body, json_encode($row, JSON_THROW_ON_ERROR));
$first = false;
}
fwrite($body, ']');
rewind($body);
$response = (new Response(200, [
'Content-Type' => 'application/json; charset=utf-8',
]))->withBody(new Stream($body));
(new Emitter())->emit($response, 65536); // chunked outputuse Psr\Http\Message\ServerRequestInterface;
function jsonHandler(ServerRequestInterface $request): \Psr\Http\Message\ResponseInterface {
$origin = $request->getHeaderLine('Origin') ?: '*';
$cors = [
'Access-Control-Allow-Origin' => $origin,
'Access-Control-Allow-Methods' => 'GET, POST, OPTIONS',
'Access-Control-Allow-Headers' => 'Content-Type, Authorization',
'Vary' => 'Origin',
];
if ($request->getMethod() === 'OPTIONS') {
return new \InitPHP\HTTP\Message\Response(204, $cors);
}
return (new \InitPHP\HTTP\Message\Response(200, $cors))
->json(['ok' => true]);
}- Response — the convenience producer's signature and trade-offs.
- Recipe — Streaming Large Files — for non-JSON streaming.
initphp/http · MIT License · part of the InitPHP family
Source · Issues · Discussions · Packagist · Contributing · Security Policy
Getting Started
PSR-7 Messages
PSR-17 Factories
PSR-18 Client
Emitter (SAPI)
Static Facades
Recipes
Reference
Migration & Help