When we cancelled the vote on PSR-7, we indicated 4 specific issues we wanted to

address:

Clarification of the with*() methods with regards to whether or not they

should allow returning the same instance if no change was made. Clarifications to the UriInterface regarding scheme delimiter handling. Clarifications to the UriInterface regarding encoding. Additions to the meta document and/or changes to UriInterface 's handling of

the path to address concerns about "base path" implementations.

We have addressed each of these four issues, plus a number of others. At this

time, we wish to open a new Review period for the proposal.

Below is a full list of updates.

Immutability and returning new instances

This addresses point number (1) above.

Previously, we stipulated that the various with*() methods MUST return a new

instance. However, in the case that no change actually occurs (e.g., same value

is provided for the component), the same instance can be safely returned. We've

updated the language of these method docblocks to read "return an instance that

contains the changed state", which allows for return $this in those specific

situations.

See:

URI updates

We now allow empty paths. This resolves issues around base path

implementations specifically. This addresses point number (4) above.

implementations specifically. This addresses point number (4) above. We moved all discussion of delimiters to get*() methods, and simply indicate

that those methods should not add delimiters (we no longer discuss removal of

delimiters). This addresses point number (2) above.

methods, and simply indicate that those methods should not add delimiters (we no longer discuss removal of delimiters). This addresses point number (2) above. Verbiage around percent-encoding was clarified to ensure intent is clear, and

to defer to RFC 3986 whenever possible; examples were added to docblocks

whenever they would help clarify intent. This addresses point number (3) above.

to defer to RFC 3986 whenever possible; examples were added to docblocks whenever they would help clarify intent. This addresses point number (3) above. Verbiage in the interface and spec was changed to reference "component"

instead of "segment", to follow RFC 3986.

See:

Headers

getHeader($name) previously would return the comma-concatenated values

associated with the header, getHeaderLines($name) would return the array of

values associated with the header, and getHeaders() would return an array of

arrays (i.e., the values returned from getHeaderLines() ). A number of

contributors felt the verbiage was difficult to follow. The following changes

were made to clarify the situation:

getHeader($name) now returns an array of string values associated with the

given header. It was also updated to indicate that it MUST return an empty

array if no header by the given name is present.

now returns an array of string values associated with the given header. It was also updated to indicate that it MUST return an empty array if no header by the given name is present. getHeaders() remains unchanged. As such, this method and getHeader($name)

are now symmetrical.

remains unchanged. As such, this method and are now symmetrical. A new method, getHeaderLine($name) returns the comma-concatenated values for

a given header. The method MUST return null if no header by that name is present.

returns the comma-concatenated values for a given header. The method MUST return null if no header by that name is present. getHeaderLines($name) was removed entirely.

We chose not to have a getHeaderLines() complement to getHeaderLine($name) ,

as there are limited, if any, use cases for it. Since not all headers can be

safely comma-concatenated (including the very common Set-Cookie header), it

typically would be an unsafe operation.

See:

Stream interface renaming

StreamableInterface was renamed to StreamInterface . This also required

changes to MessageInterface to update typehints.

See:

Throwing exceptions from streams

A discussion on the mailing list and via twitter indicated that exceptions may

be safely thrown by stream wrapper implementations. As such, we updated the

signatures of StreamInterface to have single return values for success, and to

raise exceptions on error.

See:

Host header updates

RequestInterface::withUri() was modified to accept an optional, second

argument, a $preserveHost flag, set to false by default. When false ,

implementations MUST update the Host header based on the provided URI; when

true , the Host header must be left unmodified.

See:

File uploads

File uploads have been completely rewritten. As noted in

php-fig/fig-standards#492, there are well-known issues

with how PHP handles arrays of file uploads; additionally, during discussion, we

noted a number of other areas that are problematic:

In non-POST requests, $_FILES is not populated.

is not populated. When manually parsing the request body, it's often more efficient to create

streams than to write uploaded files to the filesystem.

streams than to write uploaded files to the filesystem. In non-SAPI environments one or both of the above are often true.

These situations cause a number of interoperability issues.

We have changed the *FileParams() methods now to be *UploadedFiles() .

getUploadedFiles() is specified as returning an array tree of

Psr\Http\Message\UploadedFileInterface instances, and is expected to be in a

normalized structure that mirrors how files were submitted by the client in

terms of naming and tree depth.

UploadedFileInterface largely mimics the structure of individual elements of

the $_FILES superglobal, with a few important changes:

Unsafe operations, such as retrieving the media type and client-side filename,

are prefixed with Client to indicate they cannot be trusted.

are prefixed with to indicate they cannot be trusted. tmp_name is not represented. Instead, two other methods are introduced: move($path) , which can be expected to work regardless of environment or

how the upload is represented. getStream() , which returns a StreamInterface instance, which can be used

for purposes of interacting with the uploaded file as a stream (e.g., to use

it with stream_copy_to_stream() to upload it to cloud storage).

is not represented. Instead, two other methods are introduced:

The above changes allow easier usage in testing (you can specify php://temp

streams instead of creating actual files), and enable PSR-7 to support file

uploads in non-SAPI environments or non-POST requests.

See:

Diff

For a full diff from the time we yanked the vote until now:

Created 5 years ago | Updated 5 years ago