A little update on this issue...

> It was deliberate. I thought we'd documented it, but evidently this 
is not the case. 

It turns out, yes, it was documented after all - in the inline 
documentation block of ServerRequestInterface.

It states:

> $_SERVER values MUST be treated as immutable, as they represent 
application state at the time of request; as such, no methods are provided 
to allow modification of those values. The other values provide such 
methods, as they can be restored from $_SERVER or the request body, and may 
need treatment during the application

Unfortunately this argument is (well, excuse me, but) nonsense.

$_SERVER itself of course must be treated as immutable and does "represent 
application state at the time of request" - but it's an array, so of course 
this will be *copied* to the request model. (at least by default, unless 
you were to explicitly use the reference operator or something.)

The entire request model "represents application state at the time of 
request", so the same argument would work against modifying anything at 
all. But the model is immutable, so the argument isn't even relevant in the 
first place - you can't affect the state of $_SERVER once that state is 
copied to the model, and secondly, you can't affect the state of "server 
params" once they're in the model either, anymore than you can modify any 
other value in the model, you can only generate new request instances.

Nothing is mutable in the first place, so that line or argumentation really 
doesn't work at all.

I understand the potential harm in modifying $_SERVER, but that's not what 
we're talking about. We're not modifying any superglobals. A new 
request-model can *always* be generated again from the superglobals, at any 
time.

As you can see, this decisions leads to weirdness in the PSR-17 factory 
interface:

https://github.com/http-interop/http-factory/blob/master/src/ServerRequestFactoryInterface.php#L28

The $server argument is an artifact stemming from the fact that injecting 
$_SERVER variables can only be done in an implementation-specific manner, 
via a proprietary constructor.

Omitting this was a mistake.

And any day now, we'll have PSR-15 middleware and PSR-17 factory classes 
depending on this spec, at which point it becomes ever more difficult to 
fix - once those are in the water, I'd say it's unlikely this will *ever* 
change... :-(

But my guess is, no one wants to even deal with the process of starting a 
new PSR for this, and instead, we'll simply inherit this mistake, which 
will spread in the form of artifacts into PSR-17 and elsewhere.

I hate that we can't version a PSR. I find it hugely problematic, because 
PSR-7 is more than just a "standard" - it's a set interfaces, which are 
source-code, and there's a reason why source-code dependencies are 
versioned as packages... I understand *why* the standard can't change, it 
just doesn't change the fact that sometimes you realize too late that it 
*should*...

Time makes fools of us all :-/

On Tuesday, September 27, 2016 at 11:17:03 PM UTC+2, Matthew Weier 
O'Phinney wrote:
>
> On Mon, Sep 26, 2016 at 2:54 PM, Rasmus Schultz <ras...@mindplay.dk 
> <javascript:>> 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 <javascript:> 
> https://mwop.net/ 
>

-- 
You received this message because you are subscribed to the Google Groups "PHP 
Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to php-fig+unsubscr...@googlegroups.com.
To post to this group, send email to php-fig@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/php-fig/b75861f1-f384-490b-8531-e6e2997577bc%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to