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

Request

InitPHP\HTTP\Message\Request is the PSR-7 outbound-request message: the kind you build to send, as opposed to a ServerRequest (the kind you receive). It implements Psr\Http\Message\RequestInterface.

useInitPHP\HTTP\Message\Request;

Construction

$request = newRequest(
string $method, // "GET", "POST", ...
string|UriInterface $uri, // URL string or UriInterface
array $headers = [], // header name => value or list of values
string|resource|StreamInterface|null $body = null,
string $version = '1.1'// HTTP protocol version
);

Examples:

// Bare GET$request = newRequest('GET', 'https://api.example.com/users');
// JSON POST$request = newRequest(
'POST',
'https://api.example.com/users',
['Content-Type' => 'application/json; charset=utf-8'],
json_encode(['name' => 'Ada'])
);
// Using a pre-built Uri value object$uri = new \InitPHP\HTTP\Message\Uri('https://api.example.com/v1/users?active=true');
$request = newRequest('GET', $uri);

Reading

$request->getMethod(); // "POST"$request->getUri(); // UriInterface$request->getRequestTarget(); // "/users?active=true"$request->getProtocolVersion(); // "1.1"$request->getHeaders(); // array<string, string[]>$request->getHeader('Accept'); // string[] — empty array if missing$request->getHeaderLine('Accept'); // "application/json, text/plain"$request->hasHeader('Accept'); // bool — case-insensitive$request->getBody(); // StreamInterface

getRequestTarget() returns the explicit override (set via withRequestTarget()) or, failing that, the URI's path + query (/users?active=true). When the path is empty it falls back to /.

Convenience method predicates

On top of the PSR-7 surface, Request adds case-insensitive method-check helpers:

$request->isGet();
$request->isPost();
$request->isPut();
$request->isPatch();
$request->isDelete();
$request->isHead();
// Multi-method check$request->isMethod('PUT', 'PATCH'); // true if method matches any

These come from RequestTrait and are shared with ServerRequest.

Mutating (returns a new instance)

$updated = $request
->withMethod('PUT')
->withUri(newUri('https://api.example.com/users/42'))
->withRequestTarget('*') // OPTIONS *
->withHeader('Content-Type', 'application/json; charset=utf-8')
->withAddedHeader('X-Trace-Id', '0f1e2d')
->withoutHeader('Accept')
->withBody($newStream)
->withProtocolVersion('2');

Each call returns a fresh Request; the original is untouched. See Overview & Immutability for the deep-clone rules that make this safe.

Host header synchronisation

withUri(...) updates the Host header from the new URI unless you pass preserveHost = trueand the request already has a Host header:

$request = newRequest('GET', 'https://original.example/path');
$request->getHeaderLine('Host'); // "original.example"$updated = $request->withUri(newUri('https://elsewhere.example/'));
$updated->getHeaderLine('Host'); // "elsewhere.example"$pinned = $request->withHeader('Host', 'sticky.example')
->withUri(newUri('https://elsewhere.example/'), true);
$pinned->getHeaderLine('Host'); // "sticky.example" — preserveHost honoured

Non-standard ports are included in the synchronised Host header; standard ports (80 for http, 443 for https) are omitted:

$request->withUri(newUri('http://b.example:8080/'))->getHeaderLine('Host'); // "b.example:8080"$request->withUri(newUri('https://b.example:443/'))->getHeaderLine('Host'); // "b.example"

Setting the body from many shapes

The constructor (and setBody()) accept any of these:

ShapeWhat happens
nullAn empty body is created lazily on the first getBody() call.
stringWrapped in a new Stream (default backend: php://temp).
resourceWrapped in a new Stream directly.
StreamInterfaceStored verbatim.

See Stream for the backend selection (php://temp vs php://memory vs in-memory string vs raw resource).

Sending a Request

Request is just the value object — it does not know how to actually send itself. Pass it to a PSR-18 client:

useInitPHP\HTTP\Client\Client;
$response = (newClient())->sendRequest($request);

See PSR-18 Client.

Things that changed in v3

Earlier versions of this package bolted a _parameters parameter bag onto Request (__get, __set, all, get, has, merge) along with a Request::sendRequest() shortcut and a static Request::createFromGlobals() singleton. All of that is gone in v3:

  • Request is now strictly a PSR-7 message value object.
  • The parameter bag was a separate concern — use ServerRequest::getParsedBody() / attributes instead. See ServerRequest.
  • The static factory moved to ServerRequest::createFromGlobals() and is now stateless. See ServerRequest.
  • sendRequest() shortcut is gone — pass the request to a Client you constructed yourself (good for DI / testing).

If you're upgrading, the Migration Guide has a copy-pasteable code-mod for every removed API.

Clone this wiki locally