zendframework/zend-diactoros
zendframework/zend-diactoros provides PSR-7 HTTP message implementations for PHP, including ServerRequest, Response, Stream, UploadedFile and Uri. Useful for building middleware, APIs and frameworks with interoperable request/response handling.
SplFileInfo by the UploadedFile class. The signatures of getSize() are potentially incompatible, and UploadedFile is intended to work with arbitrary PHP and PSR-7 streams, whereas SplFileInfo can only model files on the filesystem. While this is technically a BC break, we are treating it as a bugfix, as the class was broken for many use cases.UploadedFile class to extend SplFileInfo, allowing developers to make use of those features in their applications.Zend\Diactoros\Uri class when invalid UTF-8 characters are present the user-info, path, or query string, ensuring they are URL-encoded before being consumed. Previously, such characters could result in a fatal error, which was particularly problematic when marshaling the request URI for an application request cycle.#370 updates Zend\Diactoros\marshalHeadersFromSapi() to ensure all underscores in header name keys are converted to dashes (fixing issues with header names such as CONTENT_SECURITY_POLICY, which would previously resolve improperly to content-security_policy).
#370 updates Zend\Diactoros\marshalHeadersFromSapi() to ignore header names from the $server array that resolve to integers; previously, it would raise a fatal error.
$_SERVER['HTTPS'] value such that an empty HTTPS-key will result in a scheme of http and not https.$_SERVER['HTTPS'] value
such that an empty HTTPS-key will result in a scheme of http and not
https.phpdbg to the list of accepted non-SAPI enviornments for purposes
of calling UploadedFile::moveTo().0 or 0 from the SAPI, ensuring they are detected and injected into the ServerRequest properly.0 or 0 from the
SAPI, ensuring they are detected and injected into the ServerRequest properly.ServerRequestFactory::createServerRequest() method
creates a php://temp stream instead of a php::input stream, in compliance
with the PSR-17 specification.#326 adds PSR-17 HTTP Message Factory implementations, including:
Zend\Diactoros\RequestFactoryZend\Diactoros\ResponseFactoryZend\Diactoros\ServerRequestFactoryZend\Diactoros\StreamFactoryZend\Diactoros\UploadedFileFactoryZend\Diactoros\UriFactoryThese factories may be used to produce the associated instances; we encourage users to rely on the PSR-17 factory interfaces to allow exchanging PSR-7 implementations within their applications.
#328 adds a package-level exception interface, Zend\Diactoros\Exception\ExceptionInterface,
and several implementations for specific exceptions raised within the package.
These include:
Zend\Diactoros\Exception\DeserializationException (extends UnexpectedValueException)Zend\Diactoros\Exception\InvalidArgumentException (extends InvalidArgumentException)Zend\Diactoros\Exception\InvalidStreamPointerPositionException (extends RuntimeException)Zend\Diactoros\Exception\SerializationException (extends UnexpectedValueException)Zend\Diactoros\Exception\UnreadableStreamException (extends RuntimeException)Zend\Diactoros\Exception\UnrecognizedProtocolVersionException (extends UnexpectedValueException)Zend\Diactoros\Exception\UnrewindableStreamException (extends RuntimeException)Zend\Diactoros\Exception\UnseekableStreamException (extends RuntimeException)Zend\Diactoros\Exception\UntellableStreamException (extends RuntimeException)Zend\Diactoros\Exception\UnwritableStreamException (extends RuntimeException)Zend\Diactoros\Exception\UploadedFileAlreadyMovedException (extends RuntimeException)Zend\Diactoros\Exception\UploadedFileErrorException (extends RuntimeException)#329 adds return type hints and scalar parameter type hints wherever possible. The changes were done to help improve code quality, in part by reducing manual type checking. If you are extending any classes, you may need to update your signatures; check the signatures of the class(es) you are extending for changes.
#162 modifies Serializer\Request such that it now no longer raises an UnexpectedValueException via its toString() method
when an unexpected HTTP method is encountered; this can be done safely, as the value can never
be invalid due to other changes in the same patch.
#162 modifies RequestTrait such that it now invalidates non-string method arguments to either
the constructor or withMethod(), raising an InvalidArgumentException for any that do not validate.
#308 removes the following methods from the ServerRequestFactory class:
normalizeServer() (use Zend\Diactoros\normalizeServer() instead)marshalHeaders() (use Zend\Diactoros\marshalHeadersFromSapi() instead)marshalUriFromServer() (use Zend\Diactoros\marshalUriFromSapi() instead)marshalRequestUri() (use Uri::getPath() from the Uri instance returned by marshalUriFromSapi() instead)marshalHostAndPortFromHeaders() (use Uri::getHost() and Uri::getPort() from the Uri instances returned by marshalUriFromSapi() instead)stripQueryString() (use explode("?", $path, 2)[0] instead)normalizeFiles() (use Zend\Diactoros\normalizeUploadedFiles() instead)#295 removes Zend\Diactoros\Server. You can use the RequestHandlerRunner class from
zendframework/zend-httphandlerrunner to provide these capabilities instead.
#295 removes Zend\Diactoros\Response\EmitterInterface and the various emitter implementations.
These can now be found in the package zendframework/zend-httphandlerrunner, which also provides
a PSR-7-implementation agnostic way of using them.
#325 changes the behavior of ServerRequest::withParsedBody(). Per
PSR-7, it now no longer allows values other than null, arrays, or objects.
#325 changes the behavior of each of Request, ServerRequest, and
Response in relation to the validation of header values. Previously, we
allowed empty arrays to be provided via withHeader(); however, this was
contrary to the PSR-7 specification. Empty arrays are no longer allowed.
ServerRequestFactory, which made it
impossible to fetch a specific header by name.This release modifies how ServerRequestFactory marshals the request URI. In
prior releases, we would attempt to inspect the X-Rewrite-Url and
X-Original-Url headers, using their values, if present. These headers are
issued by the ISAPI_Rewrite module for IIS (developed by HeliconTech).
However, we have no way of guaranteeing that the module is what issued the
headers, making it an unreliable source for discovering the URI. As such, we
have removed this feature in this release of Diactoros.
If you are developing a middleware application, you can mimic the functionality via middleware as follows:
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Zend\Diactoros\Uri;
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler) : ResponseInterface
{
$requestUri = null;
$httpXRewriteUrl = $request->getHeaderLine('X-Rewrite-Url');
if ($httpXRewriteUrl !== null) {
$requestUri = $httpXRewriteUrl;
}
$httpXOriginalUrl = $request->getHeaderLine('X-Original-Url');
if ($httpXOriginalUrl !== null) {
$requestUri = $httpXOriginalUrl;
}
if ($requestUri !== null) {
$request = $request->withUri(new Uri($requestUri));
}
return $handler->handle($request);
}
If you use middleware such as the above, make sure you also instruct your web server to strip any incoming headers of the same name so that you can guarantee they are issued by the ISAPI_Rewrite module.
#321 updates the logic in Uri::withPort() to ensure that it checks that the
value provided is either an integer or a string integer, as only those values
may be cast to integer without data loss.
#320 adds checking within Response to ensure that the provided reason
phrase is a string; an InvalidArgumentException is now raised if it is not. This change
ensures the class adheres strictly to the PSR-7 specification.
#319 provides a fix to Zend\Diactoros\Response that ensures that the status
code returned is always an integer (and never a string containing an
integer), thus ensuring it strictly adheres to the PSR-7 specification.
#318 fixes the logic for discovering whether an HTTPS scheme is in play to be case insensitive when comparing header and SAPI values, ensuring no false negative lookups occur.
#314 modifies error handling around opening a file resource within
Zend\Diactoros\Stream::setStream() to no longer use the second argument to
set_error_handler(), and instead check the error type in the handler itself;
this fixes an issue when the handler is nested inside another error handler,
which currently has buggy behavior within the PHP engine.
normalizeUploadedFiles() utility function handles nested trees of
uploaded files, ensuring it detects them properly.Zend\Diactoros namespace, each of
which may be used to derive artifacts from SAPI supergloabls for the purposes
of generating a ServerRequest instance:
normalizeServer(array $server, callable $apacheRequestHeaderCallback = null) : array
(main purpose is to aggregate the Authorization header in the SAPI params
when under Apache)marshalProtocolVersionFromSapi(array $server) : stringmarshalMethodFromSapi(array $server) : stringmarshalUriFromSapi(array $server, array $headers) : UrimarshalHeadersFromSapi(array $server) : arrayparseCookieHeader(string $header) : arraycreateUploadedFile(array $spec) : UploadedFile (creates the instance from
a normal $_FILES entry)normalizeUploadedFiles(array $files) : UploadedFileInterface[] (traverses
a potentially nested array of uploaded file instances and/or $_FILES
entries, including those aggregated under mod_php, php-fpm, and php-cgi in
order to create a flat array of UploadedFileInterface instances to use in a
request)#307 deprecates ServerRequestFactory::normalizeServer(); the method is
no longer used internally, and users should instead use Zend\Diactoros\normalizeServer(),
to which it proxies.
#307 deprecates ServerRequestFactory::marshalHeaders(); the method is
no longer used internally, and users should instead use Zend\Diactoros\marshalHeadersFromSapi(),
to which it proxies.
#307 deprecates ServerRequestFactory::marshalUriFromServer(); the method
is no longer used internally. Users should use marshalUriFromSapi() instead.
#307 deprecates ServerRequestFactory::marshalRequestUri(). the method is no longer
used internally, and currently proxies to marshalUriFromSapi(), pulling the
discovered path from the Uri instance returned by that function. Users
should use marshalUriFromSapi() instead.
#307 deprecates ServerRequestFactory::marshalHostAndPortFromHeaders(); the method
is no longer used internally, and currently proxies to marshalUriFromSapi(),
pulling the discovered host and port from the Uri instance returned by that
function. Users should use marshalUriFromSapi() instead.
#307 deprecates ServerRequestFactory::getHeader(); the method is no longer
used internally. Users should copy and paste the functionality into their own
applications if needed, or rely on headers from a fully-populated Uri
instance instead.
#307 deprecates ServerRequestFactory::stripQueryString(); the method is no longer
used internally, and users can mimic the functionality via the expression
$path = explode('?', $path, 2)[0];.
#307 deprecates ServerRequestFactory::normalizeFiles(); the functionality
is no longer used internally, and users can use normalizeUploadedFiles() as
a replacement.
#303 deprecates Zend\Diactoros\Response\EmitterInterface and its various implementations. These are now provided via the
zendframework/zend-httphandlerrunner package as 1:1 substitutions.
#303 deprecates the Zend\Diactoros\Server class. Users are directed to the RequestHandlerRunner class from the
zendframework/zend-httphandlerrunner package as an alternative.
uri class to ensure non-empty
values are not treated as empty.Uri::getHost() to cast the value via strtolower() before returning it. While this represents a change, it is fixing a bug in our implementation: the PSR-7 specification for the method, which follows IETF RFC 3986 section 3.2.2, requires that the host name be normalized to lowercase.Stream::getSize() such that it checks that the result of fstat was succesful before attempting to return its size member; in the case of an error, it now returns null.#285 adds a new custom response type, Zend\Diactoros\Response\XmlResponse, for generating responses representing XML. Usage is the same as with the HtmlResponse or TextResponse; the response generated will have a Content-Type: application/xml header by default.
#280 adds the response status code/phrase pairing "103 Early Hints" to the Response::$phrases property. This is a new status proposed via RFC 8297.
#279 adds explicit support for PHP 7.2; previously, we'd allowed build failures, though none occured; we now require PHP 7.2 builds to pass.
SapiEmitterTrait calls header() to ensure that a response code is always passed as the third argument; this is done to prevent PHP from silently overriding it.#270 changes the behavior of Zend\Diactoros\Server: it no longer creates an output buffer.
#270 changes the behavior of the two SAPI emitters in two backwards-incompatible ways:
They no longer auto-inject a Content-Length header. If you need this functionality, zendframework/zend-expressive-helpers 4.1+ provides it via Zend\Expressive\Helper\ContentLengthMiddleware.
They no longer flush the output buffer. Instead, if headers have been sent, or the output buffer exists and has a non-zero length, the emitters raise an exception, as mixed PSR-7/output buffer content creates a blocking issue. If you are emitting content via echo, print, var_dump, etc., or not catching PHP errors or exceptions, you will need to either fix your application to always work with a PSR-7 response, or provide your own emitters that allow mixed output mechanisms.
#205 adds support for PHP 7.2.
#250 adds a new API to JsonResponse to avoid the need for decoding the response body in order to make changes to the underlying content. New methods include:
getPayload(): retrieve the unencoded payload.withPayload($data): create a new instance with the given data.getEncodingOptions(): retrieve the flags to use when encoding the payload to JSON.withEncodingOptions(int $encodingOptions): create a new instance that uses the provided flags when encoding the payload to JSON.#249 changes the behavior of the various Uri::with*() methods slightly: if the value represents no change, these methods will return the same instance instead of a new one.
#248 changes the behavior of Uri::getUserInfo() slightly: it now (correctly) returns the percent-encoded values for the user and/or password, per RFC 3986 Section 3.2.1. withUserInfo() will percent-encode values, using a mechanism that prevents double-encoding.
#243 changes the exception messages thrown by UploadedFile::getStream() and moveTo() when an upload error exists to include details about the upload error.
#233 adds a new argument to SapiStreamEmitter::emit, $maxBufferLevel between the $response and $maxBufferLength arguments. This was done because the Server::listen() method passes only the response and $maxBufferLevel to emitters; previously, this often meant that streams were being chunked 2 bytes at a time versus the expected default of 8kb.
If you were calling the SapiStreamEmitter::emit() method manually previously, you will need to update your code.
Uri class provides user-info within the URI authority; the value is now correctly percent-encoded , per RFC 3986 Section 3.2.1.#247 fixes the Stream and RelativeStream __toString() method implementations to check if the stream isSeekable() before attempting to rewind() it, ensuring that the method does not raise exceptions (PHP does not allow exceptions in that method). In particular, this fixes an issue when using AWS S3 streams.
#252 provides a fix to the SapiEmitterTrait to ensure that any Set-Cookie headers in the response instance do not override those set by PHP when a session is created and/or regenerated.
#257 provides a fix for the PhpInputStream::read() method to ensure string content that evaluates as empty (including 0) is still cached.
#258 updates the Uri::filterPath() method to allow parens within a URI path, per RFC 3986 section 3.3 (parens are within the character set "sub-delims").
#219 adds two new classes, Zend\Diactoros\Request\ArraySerializer and Zend\Diactoros\Response\ArraySerializer. Each exposes the static methods toArray() and fromArray(), allowing de/serialization of messages from and to arrays.
#236 adds two new constants to the Response class: MIN_STATUS_CODE_VALUE and MAX_STATUS_CODE_VALUE.
#240 changes the behavior of ServerRequestFactory::fromGlobals() when no $cookies argument is present. Previously, it would use $_COOKIES; now, if a Cookie header is present, it will parse and use that to populate the instance instead.
This change allows utilizing cookies that contain period characters (.) in their names (PHP's built-in cookie handling renames these to replace . with _, which can lead to synchronization issues with clients).
#235 changes the behavior of Uri::__toString() to better follow proscribed behavior in PSR-7. In particular, prior to this release, if a scheme was missing but an authority was present, the class was incorrectly returning a value that did not include a // prefix. As of this release, it now does this correctly.
psr/http-message-implementation to simply 1.0 instead of ~1.0.0, to follow how other implementations provide PSR-7.SapiStreamEmitter causing the response body to be cast
to (string) and also be read as a readable stream, potentially producing
double output.How can I help you explore Laravel packages today?