HTTP Message
Lightweight and strict implementation of PSR-7 HTTP Message including PSR-17 HTTP Factories.
Installation
To get started, install the http-message repository via the Composer package manager:
composer require zaphyr-org/http-message
Basic usage
The http-message
repository is committed to maintaining a strict adherence to the
PSR 7 specification, and as such, it will always remain focused solely on
fulfilling the requirements outlined in this standard. We firmly believe in the principle of simplicity and purity in
design, which means that we are committed to not including any additional features or helper methods in the repository.
The approach to utilizing this package varies depending on whether you are working on an HTTP client
or a
server-side
application. To streamline the process for each scenario, specific steps need to be followed.
When developing an HTTP client
, the first step is to create and populate a Zaphyr\HttpMessage\Request
instance. This involves crafting the request with the necessary HTTP method, headers, and payload data as required by the
target server. Once the request is prepared, it is then dispatched to the server, and the client should expect to receive
a response in return. The response will be in the form of a Zaphyr\HttpMessage\Response instance, containing
valuable information such as the server's HTTP status code, response headers, and response body.
On the other hand, for server-side
applications, the process slightly differs. Here, you need to handle incoming
requests from clients. To do this, you create a Zaphyr\HttpMessage\ServerRequest instance, which
encapsulates the incoming request data received from the client. The server request object contains details such as the
request method, headers, and payload data sent by the client. Once you've processed the incoming request and performed
the necessary operations or computations, it's time to construct and populate a Zaphyr\HttpMessage\Response
instance. This response object will hold the data you wish to send back to the client as the HTTP response. It includes
the desired HTTP status code, response headers, and the response body containing the information or data generated by
the server-side
application.
Request
When working with the HTTP Message service, you, as a developer, will handle the interaction between the client and
the server. The client initiates the process by sending a request to the server, and in return, it expects to receive
a response from the server. The Zaphyr\HttpMessage\Request
implements the
PSR-7 RequestInterface:
$request = new Zaphyr\HttpMessage\Request(
method: 'GET',
uri: 'https://example.com',
body: 'ph://temp',
headers: ['Content-Type' => 'text/html'],
protocol: '1.1'
);
Both requests and responses are designed to be immutable, meaning they cannot be modified directly once created. If you
need to make changes to a request or response, such as updating headers or request parameters, you should utilize the
appropriate with*()
methods. However, it is crucial to note that when using these with*()
methods, you must capture
the return value, as it will yield a new instance with the updated changes rather than modifying the original instance:
$request = $request->withHeader('Content-Type', 'application/json');
After sending the request, you will then examine and analyze the received response:
$request->getBody()->write(json_encode($data));
$response = $client->sendRequest($request);
echo $response->getBody();
This repository does NOT come with a PSR-18 implementation out of the box. For a PSR-18 implementation, check out the HTTP Client repository.
ServerRequest
The Zaphyr\HttpMessage\ServerRequest
object represents an HTTP request received by the server. It encapsulates the
incoming request data received from the client. The server request object contains details such as the request method,
headers, and payload data sent by the client. The ServerRequest
implements the
PSR-7 ServerRequestInterface:
$serverRequest = new Zaphyr\HttpMessage\ServerRequest(
method:'GET',
uri: 'https://example.com',
body: 'php://input',
headers: getallheaders(),
protocol: '1.1',
serverParams: $_SERVER,
cookieParams: $_COOKIE,
queryParams: $_GET,
uploadedFiles: $_FILES,
);
Response
The Zaphyr\HttpMessage\Response
object serves as a concrete implementation of the
PSR-7 ResponseInterface. It functions as a
versatile object that consolidates response information for both HTTP clients
and server-side
applications. This
includes essential details such as response headers and the content of the message body.
Writing to the body does not create a state change in the response, so it can be done without capturing the return value. Manipulating headers does, however:
$response = new Zaphyr\HttpMessage\Response(
body: 'php://memory',
status: 200,
headers: ['Content-Type' => 'text/html'],
);
$response->getBody()->write("Hello World");
$response = $response->withHeader('Content-Type', 'text/plain');
Headers do not need to be added before data is written to the body!
Stream
The Zaphyr\HttpMessage\Stream
class is a wrapper around PHP streams
implementing the PSR-7 StreamInterface.
The constructor accepts a stream, which may be either:
a string stream identifier; e.g., php://input
or a filename:
$stream = new Zaphyr\HttpMessage\Stream('php://input');
or a PHP stream resource:
$resource = fopen('php://memory', 'r+');
$stream = new Zaphyr\HttpMessage\Stream($resource);
If a string stream identifier is provided, an optional second parameter may be provided, the file mode by which to
fopen
the stream:
$stream = new Zaphyr\HttpMessage\Stream('php://memory', 'wb+');
-
Zaphyr\HttpMessage\ServerRequest
objects by default use aphp://input
stream set to read-only. -
Zaphyr\HttpMessage\Response
objects by default use aphp://memory
with a mode ofwb+,
allowing binary read/write access.
URI
The Zaphyr\HttpMessage\Uri
class is meant to represent URIs according to
RFC 3986. It allows you to get and change any specific part of an URI.
For the full documentation about the Zaphyr\HttpMessage\Uri
class, please see
PSR-7 UriInterface.
The Zaphyr\HttpMessage\Uri
object only supports the http
and https
schemes:
$uri = new Zaphyr\HttpMessage\Uri("http://www.example.com/foo");
UploadedFile
The Zaphyr\HttpMessage\UploadedFile
is an implementation of the
PSR-7 UploadedFileInterface and represents
a single uploaded file within an HTTP request. It encapsulates the file's metadata and provides methods to interact with
the uploaded file as a stream or moving it to a filesystem location:
$uploadedFile = new Zaphyr\HttpMessage\UploadedFile(
streamOrFile: new Zaphyr\HttpMessage\Stream(fopen('php://temp', 'wb+')),
size: 0,
error: UPLOAD_ERR_OK,
clientFilename: 'foo.txt',
clientMediaType: 'text/plain'
);
Factories
The primary purpose of the PSR-17 HTTP Factories is to abstract the creation of HTTP message objects, such as requests and responses, from their implementations. This allows you to write code that works with any compliant PSR-17 implementation, promoting flexibility and code reuse across different PHP projects. The HTTP Message service supplies implementations of each as follows:
-
Zaphyr\HttpMessage\Factories\RequestFactory
-
Zaphyr\HttpMessage\Factories\ResponseFactory
-
Zaphyr\HttpMessage\Factories\ServerRequestFactory
-
Zaphyr\HttpMessage\Factories\StreamFactory
-
Zaphyr\HttpMessage\Factories\UploadedFileFactory
-
Zaphyr\HttpMessage\Factories\UriFactory
Example
Here's a simple example using the HTTP Message service to create a PSR-7 compliant HTTP request:
$requestFactory = new Zaphyr\HttpMessage\Factories\RequestFactory();
$request = $requestFactory->createRequest('GET', 'https://example.com');
$response = $client->sendRequest($request);
echo $response->getBody();
This repository does NOT come with a PSR-18 implementation out of the box. For a PSR-18 implementation, check out the HTTP Client repository.