polymorphine / message
PSR-7 Http message implementation
Requires
- php: ^7.4 || ^8.0
- ext-json: *
- psr/http-factory: ^1.0
- psr/http-message: ^1.0
Requires (Dev)
- polymorphine/dev: 0.2.*
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);