-
Notifications
You must be signed in to change notification settings - Fork 0
PSR 17 Factory
PSR-17 defines six factory interfaces — one per PSR-7 message type. InitPHP\HTTP\Factory\Factory implements all of them in a single class:
use InitPHP\HTTP\Factory\Factory;
$factory = new Factory();The interfaces it implements:
Psr\Http\Message\RequestFactoryInterface
Psr\Http\Message\ResponseFactoryInterface
Psr\Http\Message\ServerRequestFactoryInterface
Psr\Http\Message\StreamFactoryInterface
Psr\Http\Message\UriFactoryInterface
Psr\Http\Message\UploadedFileFactoryInterface
One concrete factory + every interface means a single DI binding can satisfy any consumer that asks for "the factory" — whether they need one of the six PSR-17 sub-interfaces specifically or the union.
// in any PSR-11 container
$container->set(
\Psr\Http\Message\RequestFactoryInterface::class,
fn () => new \InitPHP\HTTP\Factory\Factory()
);$request = $factory->createRequest('POST', 'https://api.example.com/users');Returns a Request with empty headers, an empty body and HTTP/1.1. $uri can be a string or a Psr\Http\Message\UriInterface.
$response = $factory->createResponse(201); // "Created"
$response = $factory->createResponse(418, 'Cuppa'); // explicit reasonReturns a Response. When $reasonPhrase is empty and the code is in the IANA table, the canonical phrase is used.
$request = $factory->createServerRequest('POST', '/users', $_SERVER);Returns a ServerRequest. Cookies, query, parsed body and uploaded files default to empty — set them via the with*Params() family.
$stream = $factory->createStream('payload');Returns a Stream backed by php://temp, seeded with $content. This is the default backend for "in-memory but might spill to disk" payloads — the right choice for most cases.
$stream = $factory->createStreamFromFile('/var/files/report.pdf', 'rb');Opens $filename with $mode and wraps the resulting resource. Failure modes:
- Empty
$filename→RuntimeException("Path cannot be empty"). -
$modeempty or starting with an unrecognised letter →InvalidArgumentException. Valid first letters:r,w,a,x,c. -
fopen()returns false (file missing, permission denied) →RuntimeExceptioncarrying theerror_get_last()message.
$stream = $factory->createStreamFromResource(fopen('/dev/urandom', 'rb'));Wraps an already-open resource. If $resource is already a StreamInterface, it's returned verbatim (no double-wrapping).
createUploadedFile(StreamInterface $stream, ?int $size = null, int $error = UPLOAD_ERR_OK, ?string $clientFilename = null, ?string $clientMediaType = null): UploadedFileInterface
$file = $factory->createUploadedFile($stream, 1024, UPLOAD_ERR_OK, 'me.png', 'image/png');If $size is null, $stream->getSize() is consulted — which itself may be null (pipes, sockets, indeterminate streams). That's per the PSR-7 contract; UploadedFile::getSize() is nullable. See UploadedFile.
v2 → v3 note: Earlier versions used a non-nullable
int $sizeparameter, which produced aTypeErrorwhenever you passed a stream whose size couldn't be determined. Fixed in v3.
$uri = $factory->createUri('https://api.example.com/v1/users');Parses $uri via PHP's parse_url(). An unparseable string raises InvalidArgumentException.
There's a final static facade for projects that prefer terseness over a DI binding:
use InitPHP\HTTP\Facade\Factory;
$response = Factory::createResponse(200);
$stream = Factory::createStream('payload');The facade lazily resolves a singleton on first call. See Facades for the trade-offs (testability vs. ergonomics).
- Quick Start — the factory in context.
- Request, Response, Stream, Uri, UploadedFile — the products.
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