On Mon, Sep 26, 2016 at 2:54 PM, Rasmus Schultz <
ras...@mindplay.dk> wrote:
> For some reason, a withServerParams() method appears to be missing from
> ServerRequestInterface of PSR-7.
>
> Every other model property of every interface in PSR-7 has matching get_()
> and with_() method pairs, but for some reason this was omitted for
> server-params.
>
> This is proving to be problematic and rather awkward with regards to PSR-17,
> the HTTP factory interfaces, where is has become impossible to create a
> simple, meaningful, generic interface for the creation of a
> ServerRequestInterface instance.
>
> It has lead to a highly regrettable but unavoidable inconsistency in the
> factory-interfaces, per this thread:
>
>
https://github.com/http-interop/http-factory/pull/20#issuecomment-249440215
>
> I can't find any mention of a withServerParams() method having ever been
> mentioned or discussed in this forum, and I can't find anything is the PSR-7
> spec or meta documents stating that this was deliberately omitted for any
> reason.
>
> This omission means that the initialization of server-params can only be
> done in an implementation-specific way, e.g. by a constructor or
> factory-method.
>
> Was this in deed a mere oversight, as it would seem, or an undocumented
> deliberate choice?
It was deliberate. I thought we'd documented it, but evidently this is
not the case.
Server params are a direct map to `$_SERVER`. Those values are created
exactly once, when PHP initializes, and *should not change* over the
course of the request (although it *is* possible to do so, as, like
other superglobals in PHP, it's not an immutable value; doing so can
have unexpected consequences, though).
It's very much *unlike* the other parameters:
- Query params, while they typically map to $_GET, might be something
you want to change as you traverse different layers of your
application. Additionally, depending on the Server API (SAPI), these
may need to be *calculated* based on the incoming URI.
- Cookie params typically map to $_COOKIE, but, like query parameters,
may need to be calculated from the Cookie header if the SAPI does not
provide $_COOKIE.
- Uploaded files typically maps to $_FILES... except when you have a
non-POST request, or your SAPI doesn't create $_FILES.
- Body params *can* be created from $_POST, except when you have a
non-POST request, or a non-form-urlencoded request, or your SAPI
doesn't populate the superglobal.
- Attributes, as documented, are specifically to allow for a "bucket"
to hold additional values derived from processing the request (e.g.,
products of routing).
In other words, server parameters, unlike the other parameter types,
cannot be the product of calculations, and should be static for the
given request. This is why we did not provide a `withServerParams()`
method. The expectation is that they would be injected during
instantiation.
Considering PSR-17, I still don't see what the problem is.
Implementations would likely need to have a request prototype
composed, or compose the various artifacts for generating a new
instance. Alternately, these could be provided during invocation of
the factory if desired, likely from an existing request.
> Either way, it's the sort of thing someone maintaining a piece of software
> would simply correct and version-bump on any normal day.
>
> I was told earlier today that there is no such thing as making a correction
> to a PSR, post approval, if such a correction constitutes a breaking change?
>
> I don't think I need to explain why being unable (or forbidden, or even
> discouraged) to correct mistakes in software is extremely problematic?
> You're all software developers, and you all know the realities of software
> development - software has bugs, and bugs spread, such as it would appear to
> be doing in this case.
>
> If I understand correctly, the only way to add the missing method, would be
> to start an entirely new, derivative PSR with a new number?
>
> Declaring an entirely new standard, as opposed to declaring a new version of
> an existing standard, just to fix one problem, seems unlikely to happen - it
> seems like something people would oppose on the mere grounds that PSR-7 is
> already a known, well-established, widely-used thing.
>
> In other words, people would not logically oppose this on the grounds that
> it's an insurmountable effort or in any way a severe problem to add such a
> method - most projects would be able to add this method, update their
> composer file, and upgrade to a new version of the interface in about two
> minutes.
>
> Does the nature of a PSR standard itself prevent (or at least discourage) us
> from making obvious, rational improvements?
A specification is not the same as software.
Specifications do not change, and should not, because doing so then
presents a moving target for implementors.
As an example, if I, as an implementor, read the spec one day and
implement it, I should be satisfied that my implementation can be
dropped in anywhere. Alternately, if I am a consumer of it, I should
be satisfied that if I target the specification, my code will work as
expected. However, if the specification changes, I may find that my
implementation is now missing implementation of new methods, or, as a
consumer, that I'm not passing enough arguments to an existing method,
or getting back something I did not expect.
Yes, proper versioning is necessary, but that's exactly what the
specification process provides; this is why FIG, and other standards
bodies like IETF, W3C, and ISO, provide a process for marking a
specification as obsolete or abandoned when another standard
supercedes it. When a specification is voted on and approved, it's
final. If you want to make a change, you create a *new* specification,
and, if approved, it marks the existing specification as obsolete, so
that developers can choose which to implement or target, and have a
path for doing so that does not require immediate breakage.
Implementors choose whether or not they will adopt the new standard,
but in the meantime, any software written for the existing standard
*continues to work*. That's the whole point.
It may seem like it would be easier to allow versioning a
specification. But you end up then with somebody saying, "We implement
Standard X", and then you have to ask, "Okay, but *which version*?"
Having new recommendations supercede existing ones solves that
problem.
If it helps, think of the new specification as the next major version
of the spec.
(Also, as a point of reference, PEP 3333, which is the current WSGI
standard for Python, superseded PEP 333. My point is: this happens in
*every* standards body. It's expected.)
> Please don't misunderstand me, I'm not pointing fingers or trying to accuse
> anyone of anything - I myself reviewed PSR-7 many times while it was in
> development, and never noticed this; I could have easily made this mistake
> myself, for that matter.
As noted, it isn't a mistake. It was deliberate. If you feel the
decision should be documented, I'd be happy to open an errata for the
meta document that explains the decision.
> The issue is not who's at fault, but rather, how can we fix such mistakes?
>
> And if we really, truly can't (or are severely discouraged from) fixing such
> mistakes, how can we remedy that situation?
>
> Having standards is wonderful, but being unable to correct things is
> potentially detremental to the eco-system as it leads to a kind of long-term
> decay that would appear to spread.
One thing about standards are they are intended to be long-lived. If
you make a change every time somebody comes along and disagrees with
any aspect of it, we no longer have a standard; at that point,
consensus has been lost, as we've lost the benefits of peer review and
consensus.
Standards are expected to provide the expectation that the
specification will not change, so that developers can ensure that code
written to the specification will work now and into the future. As
noted on wikipedia, "The existence of a published standard does not
imply that it is always useful or correct."
(
https://en.wikipedia.org/wiki/Technical_standard#usage) It does,
however, imply that efforts have been made to ensure it is correct and
useful by the parties creating the specification, and that, regardless
of success, any code written to it will work as specified. **It
ensures that a peer-review process was followed, and consensus
reached.**
As Magnus writes elsewhere in this thread, if we have a limited scope
of changes we want to accomplish, we can create a successor to an
existing standard relatively quickly. On top of that, as he also
notes, since it covers the same domain, the interfaces themselves
would be published under the same package as a different version most
likely anyways.
So, if we have any required changes, we can address those and consider
a new PSR. In the meantime, I hope my explanation above helps shine a
light on why we may not need to do so in this particular case.
--
Matthew Weier O'Phinney
mweiero...@gmail.com
https://mwop.net/