polymorphine / message
PSR-7 Http message implementation
Installs: 23
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 1
Forks: 0
Open Issues: 0
pkg:composer/polymorphine/message
Requires
- php: ^7.4 || ^8.0
- ext-json: *
- psr/http-factory: ^1.1
- psr/http-message: ^1.1 || ^2.0
Requires (Dev)
- polymorphine/dev: 0.6.*
README
PSR-7 Http message implementation
Installation with Composer
composer require polymorphine/message
Basic usage
Public API of base classes in this package is an implementation of PSR-7: HTTP message interfaces and won't be described here. Below you'll find description of object instantiation methods and their parameter formatting specific to this package.
PSR-17 Factories
Not every aspect of created objects can be changed with mutation methods (like in UriInterface),
that's where the need for common factory interfaces came from. Packages that want to rely on abstract
psr/message interface, and retain control of passing immutable parameters to encapsulated objects from
within their classes will depend on PSR-17: HTTP Factories.
For interoperability reasons Package includes implementations of these factories.
Direct instantiation
Constructor instantiation for each of the classes described below allows to create fully configured objects, and since some of them contains many encapsulated parameters instantiating such object might be tedious and unreadable. For some, frequently created objects static constructors are provided to pass some predefined parameters.
ServerRequest
The straight forward way is to instantiate ServerRequest from
server globals using ServerRequest::fromGlobals() named constructor and optionally overriding
its parameters passing array with server, get, post, cookie or files keys:
use Polymorphine\Message\ServerRequest; $override['get'] = ['id' => 123]; $request = ServerRequest::fromGlobals($override);
This will be most typical way to create ServerRequest instance. Because complete ServerRequest contains large amount of data, other methods of instantiation in production application use cases would require much more effort, and they'll be used mostly for testing with only necessary values provided. For example instead overriding server provided data you can fake it entirely by passing filled arrays to factory's constructor:
use Polymorphine\Message\ServerRequest; use Polymorphine\Message\ServerData; $request = new ServerRequest::fromServerData(new ServerData([ 'server' => [...], 'get' => [...], 'post' => [...], 'cookie' => [...], 'files' => [...] ]));
Or create new instance directly passing various parameters: request method string, UriInterface,
StreamInterface body, headers array and parameters with UploadedFileInterface array, protocol
version, parsed body, cookie array... etc. Check ServerRequest constructor
phpDoc and some of its parameters implementations for more details.
Request & Response
Request can be created with constructor similar to used in ServerRequest,
but $params array uses only version and target keys that defaults to 1.1 and string resolved
from $uri parameter.
Response comes with several convenient static constructors that create instance
preconfigured with status code or specific headers (usually Content-Type). Default constructor
parameters are similar to Request constructor where method and Uri were replaced by status code,
and reason phrase instead target in params.
Uri, Stream & UploadedFile
Default constructor for Uri requires array of segments, which is not convenient, but
static Uri::fromString() method will create instance by parsing supplied string.
Constructor for Stream takes stream resource type, but two static methods will
help creating one - either with uri and access mode or with body string to encapsulate.
UploadedFile all constructor parameters can be derived from server's $_FILES
superglobal. Actually all, except StreamInterface, could be passed directly. Secondary constructor
method - UploadedFile::fromFileArray() - is a convenient way of translating superglobal into class
instance creating stream instance in the process.
Note that for multiple files superglobal data structure is populated in somewhat transposed fashion,
so extracting it to create multiple instances of UploadedFile requires some iterations over its
nested structure. Since these objects will be used mostly as server request property, instances for
multiple files are created within ServerData object. You can use this class
to create the array of multiple uploaded files from transposed array (normally $_FILES) if you
want to do it separately:
$serverData = new ServerData(['files' => $_FILES]); $uploadedFiles = $serverData->uploadeFiles();
UploadedFile for non-SAPI environments
UploadedFileFactory by default creates UploadedFile instance
for web server environments, which support $_FILES superglobal and security mechanism that can tell
whether given file was really uploaded or not (you cannot simply pick any file in the filesystem and
move it somewhere else). In case of other types of http servers (like command line scripts listening
for http requests in some event loop), you cannot use move_uploaded_file() function and need to
handle this process differently.
Package includes NonSAPIUploadedFile that can move file (stream) in
non-SAPI environments, but security part (recognising that file was uploaded) depends on implementation
and should be resolved internally (when creating stream).
You can create its instance directly or with factory that was instantiated with specific sapi name
(for example: cli) or empty string. You can also resolve it automatically and create either
UploadedFile or NonSAPIUploadedFile depending on predefined PHP_SAPI constant:
$factory = new UploadedFileFactory(PHP_SAPI); $file = $factory->createUploadedFile($stream);