Re: [PHP-DEV] RFC: Server-Side Request and Response Objects (v2)

This is only part of a thread. view whole thread
  108701
February 20, 2020 14:56 pmjones@pmjones.io ("Paul M. Jones")
Hi Rowan,

> On Feb 19, 2020, at 16:43, Rowan Tommins collins@gmail.com> wrote: > >>> - When working out the details, what code should we be picturing using the new classes? >> >> Not to be flippant, but: request-reading and response-writing code? > > The reason I keep trying to pin you down on this is that I am concerned about the "jack of all trades" effect - that a feature which lacks focus can end up being less useful than if it was refined for one job. From the point of view of a reviewer, it's also hard to answer the question "do you think this is a good design?" when you don't know what it's the design for. > > ... it's easier to get specific about a design fitting a goal than making an abstract judgement about it.
The purpose of the extension is as stated in the RFC: that is, to provide "an object-oriented approach around request and response functionality already existing in PHP ... an object-oriented alternative to superglobals, header(), setcookie(), setrawcookie(), and so on." At this point, I get the impression that either one of use is underthinking things, or the other one is overthinking them -- or perhaps we just have different premises and visions.
> The particular selection of fields feels rather arbitrary, though - for instance, I've never heard of "Content-MD5",
That's fair; once some of the content-related header fields came into play, it seemed reasonable to bring all of them in.
> but would have expected at least some URL-related properties, like Host.
Aha! If nothing else, then, this conversation has revealed a documentation flaw: specifically, my failure to document the ServerRequest $url property. That failure is now remedied: <https://github.com/pmjones/ext-request#the-url-array>
> Similarly, methods can have parameters, and that can be a great way of introducing opt-in behaviour. For instance, maybe in future someone requests that getMethod() should have a $allow_override flag, which set to false would ignore the X-HTTP-METHOD-OVERRIDE header. With properties, you need a separate property for every possible combination, and you have to come up with names for them all.
I get the need for future extension, which is why the method space is left open for consumers. If they want to provide their own getter methods, calculating from the existing properties or other values, they are in the clear to do so.
>> I think $uploads is a pretty distinct name, while being clearly related to files. > > Perhaps "descriptive" would be a better word than "distinct". I can tell $files and $uploads apart at a glance, but the names tell me nothing about why both exist, or which I should be using.
Which is the purpose of the documentation; it describes the differences between $files and $uploads.
>>>> Another "hard" problem is carrying those values around in the system once they are decoupled from global state; the objects in this RFC purport to do so. >> I answered this above, but to reiterate: "carrying around" is *one* thing ServerRequest does, but not *all* it does. > I'm not disputing that; I'm disputing that that particular feature is in any way a hard problem.
Your disputation is noted.
>> I admit I considered this. However, it makes more sense to me in terms of symmetry/complementarity, and in terms of "what we need on a daily basis", to provide both the request object and the response object together. > > One oddity of the proposal is that the two objects aren't actually very symmetrical.
That's fair; strike "symmetry" and retain "complementarity."
>> Maybe? I can similarly imagine that if new-and-different superglobals appear, the ServerRequest object can evolve to contain and/or translate between them. > > Although we can't predict the future, there are things we can do to make it more likely we could adapt to such a change. We should make a conscious decision whether this is a goal, or something we're happy not to focus on.
The RFC states, under Future Scope, "This extension acts as an object-oriented wrapper around existing PHP request and response functionality; as the scope of that PHP functionality expands, this extension should expand with it."
>>> Parsing a request body from an arbitrary source into arrays that match the structure of $_POST and $_FILES would be a really useful feature. >> Yes, although one can do at least the $_POST portion with ServerRequest as it is now. >> ... >> Call `$request = (new ServerRequestFactory())->new();` and voila: the equivalent of `$_POST`, populated from JSON content, stored as $request->input. > > I was actually thinking of the opposite: given a request body which didn't come from global state, but which contains data in multipart/form-data format, extract the key-value pairs and attached files.
Is that something PHP "itself" already does? If not, I have to consider it out-of-scope for this RFC.
> Rather than accepting the content body as an optional constructor parameter, what if there were two named constructors: > > - fromSuperGlobalArrays($server, $cookie, $post, $get, $files) > - fromRawRequestBody($server, $cookie, $body)
If consumers/users of ext-request wish to create factories or builders to instantiate a ServerRequest instance, it is within their purview to do so.
> In the first case, accessing the raw body on the object could give null, because none is known - defaulting to global state seems like a mistake if decoupling from global state is an explicit aim.
Your point on global state is well-taken; I will try to remember in future to phrase it as "global *mutable* state." (AFAICT, php://input is not mutable, though as you correctly point out, it is global.)
> if you look at pretty much any existing Request wrapper, it will make some attempt to extract a URL from the $_SERVER array. That really feels like a missing feature of this one right now.
Yeah, my bad on not documenting it earlier -- please consider the "missing" feature "found." ;-)
> I hope my comments aren't coming across as too negative.
Not "negative", but as you say ...
> Maybe our visions for what this should be are just too different
.... I think your goals are loftier here than proposal's. -- Paul M. Jones pmjones@pmjones.io http://paul-m-jones.com Modernizing Legacy Applications in PHP https://leanpub.com/mlaphp Solving the N+1 Problem in PHP https://leanpub.com/sn1php
  108746
February 24, 2020 21:47 rowan.collins@gmail.com (Rowan Tommins)
Hi Paul,

I left this thread to settle a bit, because I felt we were going round 
in circles a bit. I think there's some fundamental differences in 
outlook that no amount of discussion is going to resolve, so I've 
trimmed this reply to the more specific points.



On 20/02/2020 14:56, Paul M. Jones wrote:
> Aha! If nothing else, then, this conversation has revealed a > documentation flaw: specifically, my failure to document the > ServerRequest $url property. That failure is now remedied: > <https://github.com/pmjones/ext-request#the-url-array>
Aha indeed! When I was talking about "selling it to me", this is exactly the kind of thing I was looking for. This kind of functionality is much more interesting to me than copying half a dozen arrays from constructor parameters into read-only properties.
> Which is the purpose of the documentation; it describes the differences between $files and $uploads.
That's no reason not to *try* for descriptive names, though. I presume the idea is that one array is expected to be more useful for new code, and the other is mostly there for compatibility with old code? If so, perhaps the names could reflect that somehow. Incidentally, the current documentation doesn't describe the differences particularly well, just saying one is "more like $_POST". Some details of the structure, or examples comparing the two arrays, would be useful.
>> I was actually thinking of the opposite: given a request body which didn't come from global state, but which contains data in multipart/form-data format, extract the key-value pairs and attached files. > Is that something PHP "itself" already does? If not, I have to consider it out-of-scope for this RFC.
a) Yes: Every time you submit a form as multipart/form-data, PHP parses it into the global state. If this object is aiming to abstract away from global state, then having a non-global-state parser for that seems consistent. b) No: There is no function which currently takes a string and returns an array for this scenario. However, that's true of other features you have included, such as parsing accept headers, or even extracting just HTTP headers from a copy of the $_SERVER array.
> Your point on global state is well-taken; I will try to remember in future to phrase it as "global *mutable* state." (AFAICT, php://input is not mutable, though as you correctly point out, it is global.)
This distinction seems unnecessary. Once created, the object avoids global state because it is self-contained, and the fact that it's read-only is a separate attribute. We're really just talking about ways to construct that self-contained state, and "everything from global state" or "nothing from global state" seem like more natural options than "one thing from global state, everything else not". Regards, -- Rowan Tommins (né Collins) [IMSoP]
  108771
February 26, 2020 16:42 pmjones@pmjones.io ("Paul M. Jones")
Hi Rowan,

> On Feb 24, 2020, at 15:47, Rowan Tommins collins@gmail.com> wrote: > > Hi Paul, > > I left this thread to settle a bit, because I felt we were going round in circles a bit. I think there's some fundamental differences in outlook that no amount of discussion is going to resolve, so I've trimmed this reply to the more specific points.
I appreciate you taking the trouble; thanks.
>> Which is the purpose of the documentation; it describes the differences between $files and $uploads. > > That's no reason not to *try* for descriptive names, though. I presume the idea is that one array is expected to be more useful for new code, and the other is mostly there for compatibility with old code? If so, perhaps the names could reflect that somehow.
Your presumption is correct! And your point on trying for better names is well-taken -- though I think these are "expected" names, based on my research into existing implementations. The most-common names are ... - the word "files" for unparsed or unmodified $_FILES values, leading me to think $files is well-understood - the words "upload(s)", "fileUpload(s)", or "uploadedFile(s)" for parsed, transformed, or restructured $_FILES values, leading me to think $uploads is well-understood And the current users of the 1.x version have not reported confusion or trouble with the names as they are. Having said that, I am open to suggestion here. What names do you think would be better than the ones presented, contra pre-existing work from other authors?
> Incidentally, the current documentation doesn't describe the differences particularly well, just saying one is "more like $_POST". Some details of the structure, or examples comparing the two arrays, would be useful.
Good call! On your suggestion, I have added details at <https://github.com/pmjones/ext-request#the-uploads-array>. Suggestions for improvement are welcome.
>>> I was actually thinking of the opposite: given a request body which didn't come from global state, but which contains data in multipart/form-data format, extract the key-value pairs and attached files. >> Is that something PHP "itself" already does? If not, I have to consider it out-of-scope for this RFC. > > > a) Yes: Every time you submit a form as multipart/form-data, PHP parses it into the global state. If this object is aiming to abstract away from global state, then having a non-global-state parser for that seems consistent. > > b) No: There is no function which currently takes a string and returns an array for this scenario. However, that's true of other features you have included, such as parsing accept headers, or even extracting just HTTP headers from a copy of the $_SERVER array.
Quite a lot packed into four sentences; I'll try to address all of it. - First off, "yes and no" is a great answer, the most-accurate one possible. It highlights what I'm getting at: PHP transforms the content body into $_POST under some circumstances but not others. The RFC proposes to honor that existing PHP behavior. - "If this object is aiming to abstract away from global state" -- well, global *mutable* state, anyway, per our last exchange (and noted again below). - "There is no function which currently takes a string and returns an array for this scenario." -- True, though (and not to undermine my own case) there is json_decode(), which can return an array. But then the trouble is how to decide when to apply it, and with what parameters, and how to trap & report errors, etc., all of which adds complexity to what I think ought to be a simple object. And then once special treatment is given to JSON, what about XML? Etc., etc. Given all that, it strikes me that the cases not already served by PHP for parsing the body content into $_POST are best left to consumers of ServerRequest. - "However, that's true of other features you have included" -- also true, though those are informed by research into existing implementations, and provide what appear to be commonly- or frequently-needed values and structures. (You may opine this is contradictory, in which case I will respond as Whitman: "Do I contradict myself? Very well, then I contradict myself. I am large, I contain multitudes." ;-)
>> Your point on global state is well-taken; I will try to remember in future to phrase it as "global *mutable* state." (AFAICT, php://input is not mutable, though as you correctly point out, it is global.) > > This distinction seems unnecessary. Once created, the object avoids global state because it is self-contained, and the fact that it's read-only is a separate attribute. We're really just talking about ways to construct that self-contained state, and "everything from global state" or "nothing from global state" seem like more natural options than "one thing from global state, everything else not".
I agree that the default $content value is an exception to everything else in ServerRequest. While it stays read-only, it does get read from php://input each time you refer to it. The alternative is to read from php://input once at construction time (when the construct $content argument is null) and retain that value in $content from the start. But in that case, when you have very large content bodies (as when there are PUT file uploads or other large payloads), then ServerRequest takes up a lot of memory, when it might not ever be used directly. Yes, "it might never be used" could be true of every element on ServerRequest, but the maximum memory use for those other elements tends to be rather smaller. In the end, letting $content read from php://input on the fly is a reasonable tradeoff; an exception that tests the rule, if you will. Over to you! -- Paul M. Jones pmjones@pmjones.io http://paul-m-jones.com Modernizing Legacy Applications in PHP https://leanpub.com/mlaphp Solving the N+1 Problem in PHP https://leanpub.com/sn1php
  108774
February 26, 2020 18:55 rowan.collins@gmail.com (Rowan Tommins)
On Wed, 26 Feb 2020 at 16:42, Paul M. Jones <pmjones@pmjones.io> wrote:

> Your presumption is correct! And your point on trying for better names is > well-taken -- though I think these are "expected" names, based on my > research into existing implementations. The most-common names are ... > > - the word "files" for unparsed or unmodified $_FILES values, leading me > to think $files is well-understood > > - the words "upload(s)", "fileUpload(s)", or "uploadedFile(s)" for parsed, > transformed, or restructured $_FILES values, leading me to think $uploads > is well-understood >
That's a reasonable justification. Just to check, are there other implementations that have both of these names side by side, or do most implementations have one or the other, but using this naming? The main confusion I can see is having to remember which two of these is an error without having to read the docs each time: isset( $request->files['attachment']['name'][0] ); isset( $request->files['attachment'][0]['name'] ); isset( $request->uploads['attachment']['name'][0] ); isset( $request->uploads['attachment'][0]['name'] );
> Having said that, I am open to suggestion here. What names do you think > would be better than the ones presented, contra pre-existing work from > other authors? >
Looking at the examples, the difference is rather similar to the PREG_PATTERN_ORDER and PREG_SET_ORDER options to preg_match_all. If getUploads was a method, it could take a similar behaviour switch - GROUP_BY_ITEM vs GROUP_BY_ATTRIBUTE or similar. For a property, that would have to be part of the name, like $uploadsByItem and $uploadsByAttribute, which are a bit ugly. Alternatively, you could lean more heavily on the legacy aspect, and have $uploads and $uploadsLegacyFormat or something like that.
> Incidentally, the current documentation doesn't describe the differences > particularly well, just saying one is "more like $_POST". Some details of > the structure, or examples comparing the two arrays, would be useful. > > Good call! On your suggestion, I have added details at < > https://github.com/pmjones/ext-request#the-uploads-array>. Suggestions > for improvement are welcome. >
Thanks, that makes it a lot clearer. :)
> - "There is no function which currently takes a string and returns an > array for this scenario." -- True, though (and not to undermine my own > case) there is json_decode(), which can return an array. But then the > trouble is how to decide when to apply it, and with what parameters, and > how to trap & report errors, etc., all of which adds complexity to what I > think ought to be a simple object. And then once special treatment is given > to JSON, what about XML? Etc., etc. Given all that, it strikes me that the > cases not already served by PHP for parsing the body content into $_POST > are best left to consumers of ServerRequest. >
Again, any mention of JSON or XML is drifting away from what I'm asking for. What I'm asking for (or rather, suggesting would be a useful and consistent addition) is a way to do *exactly what PHP does right now*, but based on a given input string, rather than the initial request. I am totally happy with users needing to add any support for JSON, XML, etc, just like they would have to populate $_POST manually.
> I agree that the default $content value is an exception to everything else > in ServerRequest. While it stays read-only, it does get read from > php://input each time you refer to it. > > The alternative is to read from php://input once at construction time > (when the construct $content argument is null) and retain that value in > $content from the start. But in that case, when you have very large content > bodies (as when there are PUT file uploads or other large payloads), then > ServerRequest takes up a lot of memory, when it might not ever be used > directly. Yes, "it might never be used" could be true of every element on > ServerRequest, but the maximum memory use for those other elements tends to > be rather smaller. >
That's a reasonable justification. I guess that's why PSR-7 exposes it as a stream, even though that causes a whole load of pain. To play devil's advocate, does the property belong in the object at all? If it doesn't interact with any of the other properties (e.g. populating $post and $uploads based on form data), could "better syntax for getting raw request for global state" be a separate feature. Then again, maybe the ability to over-ride it in the constructor is enough to make it useful. Regards, -- Rowan Tommins [IMSoP]
  108776
February 26, 2020 19:57 pmjones@pmjones.io ("Paul M. Jones")
Hi Rowan,

> On Feb 26, 2020, at 12:55, Rowan Tommins collins@gmail.com> wrote: > > That's a reasonable justification. Just to check, are there other > implementations that have both of these names side by side, or do most > implementations have one or the other, but using this naming?
My recollection is that they have one or the other, but none with both side-by-side. (A very few have neither.)
> The main confusion I can see is having to remember which two of these is an > error without having to read the docs each time: > > isset( $request->files['attachment']['name'][0] ); > isset( $request->files['attachment'][0]['name'] ); > isset( $request->uploads['attachment']['name'][0] ); > isset( $request->uploads['attachment'][0]['name'] );
/me nods While I too have imagined that, my impression has been that consumers of 1.x use $files unless & until they change their systems to use $uploads, at which point they switch over entirely to $uploads. Given that, my concerns (such as they may have been) are soothed.
> If getUploads was a method, it could take a similar behaviour switch - > GROUP_BY_ITEM vs GROUP_BY_ATTRIBUTE or similar. For a property, that would > have to be part of the name, like $uploadsByItem and $uploadsByAttribute, > which are a bit ugly. > > Alternatively, you could lean more heavily on the legacy aspect, and have > $uploads and $uploadsLegacyFormat or something like that.
Noted. Are there any others here who feel that the names $files and $uploads are "too confusing" (for whatever values of "confusing" you find appropriate) ?
> Again, any mention of JSON or XML is drifting away from what I'm asking > for.
Ah, my bad then.
> What I'm asking for (or rather, suggesting would be a useful and > consistent addition) is a way to do *exactly what PHP does right now*, but > based on a given input string, rather than the initial request.
I'm sorry, I'm still having trouble seeing what you're getting at. Do you mean something like this in the ServerRequest constructor? public function __construct(array $globals, ?string $content = null) { if ( ($globals['_POST'] ?? null) === null && strtolower($globals['_SERVER']['CONTENT_TYPE']) === 'application/x-www-form-urlencoded' ) { if ($content === null) { $content = file_get_contents('php://input'); } $globals['_POST'] = []; parse_str($content, $globals['_POST']); } // ... } If so, it seems unnecessary for the goals of this RFC, even overkill. If not, then I await correction.
> To play devil's advocate, does the [$content] property belong in the object at all? If it doesn't interact with any of the other properties (e.g. populating $post and $uploads based on form data), could "better syntax for getting raw request for global state" be a separate feature. Then again, maybe the ability to over-ride it in the constructor is enough to make it useful.
I continue to think it does belong there. Often enough, API developers will read php://input to decode JSON or XML they find there, so having it easily-available as $request->content is appealing. To boot, the other content-related headers are present, so might as well have the content itself there too. And as you note, it's easy enough to pass in custom $content via the constructor, e.g. for testing. * * * I feel that if these are the discussion points, then we are close to exhausting the topic (even if we do not agree on everything). Thank you for your diligence and attention to detail! -- Paul M. Jones pmjones@pmjones.io http://paul-m-jones.com Modernizing Legacy Applications in PHP https://leanpub.com/mlaphp Solving the N+1 Problem in PHP https://leanpub.com/sn1php
  108777
February 26, 2020 20:12 rowan.collins@gmail.com (Rowan Tommins)
On 26/02/2020 19:57, Paul M. Jones wrote:
> I'm sorry, I'm still having trouble seeing what you're getting at. Do you mean something like this in the ServerRequest constructor? > > public function __construct(array $globals, ?string $content = null) > { > if ( > ($globals['_POST'] ?? null) === null > && > strtolower($globals['_SERVER']['CONTENT_TYPE']) === 'application/x-www-form-urlencoded' > ) { > if ($content === null) { > $content = file_get_contents('php://input'); > } > $globals['_POST'] = []; > parse_str($content, $globals['_POST']); > } > > // ... > }
That's the easy part, yes; the harder part is this: if ( ($globals['_POST'] ?? null) === null && strtolower($globals['_SERVER']['CONTENT_TYPE']) === 'multipart/form-data' ) { if ($content === null) { $content = file_get_contents('php://input'); } [ $globals['_POST'], $globals['_FILE'] ] = parse_multipart_form_data($content); } Where parse_multipart_form_data is a function which doesn't currently exist, but whose logic must all be there in the core somewhere, because everything shows up in $_POST and $_FILES when you process such a request. Recreating that functionality in userland is non-trivial, but is essential for several use cases, e.g. an event-based server like ReactPHP, or a test using a saved request body as a fixture. If both content types (application/x-www-form-urlencoded and multipart/form-data) were handled, it would also mean that the relationship $content -> $input would match the relationship php://input -> $_POST by default, which seems consistent with the aim of matching existing behaviour. Regards, -- Rowan Tommins (né Collins) [IMSoP]
  108779
February 27, 2020 02:43 pmjones@pmjones.io (Paul M . Jones)
> On Feb 26, 2020, at 14:12, Rowan Tommins collins@gmail.com> wrote: > > On 26/02/2020 19:57, Paul M. Jones wrote: > >> Do you mean something like this in the ServerRequest constructor? >> >> ... > > That's the easy part, yes; the harder part is this: > > ...
Yes, that would definitely be the harder part.
> Recreating that functionality in userland is non-trivial, but is essential for several use cases, e.g. an event-based server like ReactPHP, or a test using a saved request body as a fixture. > > If both content types (application/x-www-form-urlencoded and multipart/form-data) were handled, it would also mean that the relationship $content -> $input would match the relationship php://input -> $_POST by default, which seems consistent with the aim of matching existing behaviour.
Yes, it would indeed. However, it strikes me that the thing to do here is not to try and embed that behavior in ServerRequest; rather, it would be to expose the existing functionality on its own, so that ReactPHP (and many others!) can use them, instead of having to roll their own in userland (a la <https://github.com/reactphp/http/blob/master/src/Io/MultipartParser.php>).. -- Paul M. Jones pmjones@pmjones.io http://paul-m-jones.com Modernizing Legacy Applications in PHP https://leanpub.com/mlaphp Solving the N+1 Problem in PHP https://leanpub.com/sn1php
  108781
February 27, 2020 09:43 rowan.collins@gmail.com (Rowan Tommins)
On Thu, 27 Feb 2020 at 02:43, Paul M. Jones <pmjones@pmjones.io> wrote:

> > Recreating that functionality in userland is non-trivial, but is > essential for several use cases, e.g. an event-based server like ReactPHP, > or a test using a saved request body as a fixture. > > > > If both content types (application/x-www-form-urlencoded and > multipart/form-data) were handled, it would also mean that the relationship > $content -> $input would match the relationship php://input -> $_POST by > default, which seems consistent with the aim of matching existing behaviour. > > Yes, it would indeed. However, it strikes me that the thing to do here is > not to try and embed that behavior in ServerRequest; rather, it would be to > expose the existing functionality on its own, so that ReactPHP (and many > others!) can use them, instead of having to roll their own in userland (a > la < > https://github.com/reactphp/http/blob/master/src/Io/MultipartParser.php>). >
Why not hope that ReactPHP and others will want to use this object, precisely because it avoids them having to roll their own implementations of things? If your concern is that the object should only wrap up features that are also available via some other mechanism, I'll point again at the $accept array, which AFAIK is a useful piece of parsing which is not available outside the proposed object's constructor. If anything, that's *more* special to this object, because what I'm proposing would directly parallel the existing behaviour of $_POST and $_FILES. If somebody really wanted to use the parser without the rest of the object, they could trivially wrap it in a function: function parse_multipart_form_data($content) { $request = new ServerRequest([], $content); return [ 'input' => $request->input, 'uploads' => $request->uploads ]; } The only downside I can see to adding it is complexity of implementation. But that's at best a reason to say "we'll hope to add this later" rather than "it would be better not to add it". Regards, -- Rowan Tommins [IMSoP]
  108782
February 27, 2020 15:55 pmjones@pmjones.io ("Paul M. Jones")
Hi Rowan,


> Why not hope that ReactPHP and others will want to use this object, > precisely because it avoids them having to roll their own implementations > of things?
Like I said earlier: if React ends up wanting to use ext/request, with its tradeoffs, of course I would think that's great. But if they want to keep using what they have already, with its own tradeoffs, that's great too.
> If somebody really wanted to use the parser without the rest of the object, > they could trivially wrap it in a function: > > function parse_multipart_form_data($content) { > $request = new ServerRequest([], $content); > return [ 'input' => $request->input, 'uploads' => $request->uploads ]; > }
This is very similar to what I'm saying: to use your phrasing, I opine it is better to "trivially wrap" the existing PHP functionality as part of a separate RFC, rather than try to embed it in ServerRequest (exposed or otherwise). To reiterate what I've said before: this RFC is a relatively conservative one. The vision around it is to stay pretty close to PHP as-it-is, and to incorporate those things from the researched implementations that show up over and over again. I know that does not lead quickly toward (what I surmise is) your vision of overhauling how PHP presents global state, but an overhaul of that kind is just not what this RFC aims to do. -- Paul M. Jones pmjones@pmjones.io http://paul-m-jones.com Modernizing Legacy Applications in PHP https://leanpub.com/mlaphp Solving the N+1 Problem in PHP https://leanpub.com/sn1php
  108783
February 27, 2020 16:57 rowan.collins@gmail.com (Rowan Tommins)
On Thu, 27 Feb 2020 at 15:55, Paul M. Jones <pmjones@pmjones.io> wrote:

> > Why not hope that ReactPHP and others will want to use this object, > > precisely because it avoids them having to roll their own implementations > > of things? > > Like I said earlier: if React ends up wanting to use ext/request, with its > tradeoffs, of course I would think that's great. But if they want to keep > using what they have already, with its own tradeoffs, that's great too. >
This is one place our attitudes differ: if I was proposing something like this to be included in every copy of PHP, I'd actively want people to use it, and consider that a measure of success; you seem to be happy to just put it out there and see. As such, I perhaps place greater value on functionality that would make it more attractive, and less value on matching what we already have.
> This is very similar to what I'm saying: to use your phrasing, I opine it > is better to "trivially wrap" the existing PHP functionality as part of a > separate RFC, rather than try to embed it in ServerRequest (exposed or > otherwise). >
That's not really the same, no. I am saying that once you have the parsing functionality somewhere in userland, whether it's inside ServerRequest or its own function doesn't matter, you could still use it to delete 300+ lines of code from ReactPHP. That's a reason to add it *as soon as possible*, even if in an ideal world it would be implemented in a slightly different place, or two different places, or whatever. Regards, -- Rowan Tommins [IMSoP]
  108784
February 27, 2020 17:06 pmjones@pmjones.io ("Paul M. Jones")
Hi Rowan,

> On Feb 27, 2020, at 10:57, Rowan Tommins collins@gmail.com> wrote: > > you seem to be happy to just put it out there and see
Perhaps it was not your intent, but even so: please don't put words in my mouth. We spoke of this before; quoting myself from <https://externals.io/message/108436#108650> ...
> I don't *expect* anything from existing published library authors; however ... > > • I *suspect* that some will choose to ignore this extension, > > • that others will decorate or extend it, > > • and that still others may find their own work so close to this extension that they migrate over to it entirely.
I continue to hold that position. -- Paul M. Jones pmjones@pmjones.io http://paul-m-jones.com Modernizing Legacy Applications in PHP https://leanpub.com/mlaphp Solving the N+1 Problem in PHP https://leanpub.com/sn1php
  108785
February 27, 2020 17:27 rowan.collins@gmail.com (Rowan Tommins)
On Thu, 27 Feb 2020 at 17:06, Paul M. Jones <pmjones@pmjones.io> wrote:

> Hi Rowan, > > > On Feb 27, 2020, at 10:57, Rowan Tommins collins@gmail.com> > wrote: > > > > you seem to be happy to just put it out there and see > > Perhaps it was not your intent, but even so: please don't put words in my > mouth. We spoke of this before; quoting myself from < > https://externals.io/message/108436#108650> ... > > > I don't *expect* anything from existing published library authors; > however ... > > > > • I *suspect* that some will choose to ignore this extension, > > > > • that others will decorate or extend it, > > > > • and that still others may find their own work so close to this > extension that they migrate over to it entirely. > > I continue to hold that position. >
Perhaps I am over-interpreting them, but the words you choose always seem to me very passive, as though shrugging and saying "it might happen, or it might not". In the exchange quoted above, I can see why "expect" might have felt too strong, but "suspect" is right at the other extreme; do you also "hope", "desire", or "want" people to use it? Regards, -- Rowan Tommins [IMSoP]
  108786
February 27, 2020 17:52 pmjones@pmjones.io ("Paul M. Jones")
Hi Rowan,

> On Feb 27, 2020, at 11:27, Rowan Tommins collins@gmail.com> wrote: > > On Thu, 27 Feb 2020 at 17:06, Paul M. Jones <pmjones@pmjones.io> wrote: > >> We spoke of this before; quoting myself from <https://externals.io/message/108436#108650> ... >> >>> I don't *expect* anything from existing published library authors; however ... >>> >>> • I *suspect* that some will choose to ignore this extension, >>> >>> • that others will decorate or extend it, >>> >>> • and that still others may find their own work so close to ths extension that they migrate over to it entirely. >> >> I continue to hold that position. > > Perhaps I am over-interpreting them, but the words you choose always seem to me very passive, as though shrugging and saying "it might happen, or it might not".
It could be that you are over-interpreting; in point of fact, some combination of those three things is guaranteed to happen, no "might" about it. In any case, we seem to have drifted from evaluation of the proposal (per se) to other topics. -- Paul M. Jones pmjones@pmjones.io http://paul-m-jones.com Modernizing Legacy Applications in PHP https://leanpub.com/mlaphp Solving the N+1 Problem in PHP https://leanpub.com/sn1php
  108787
February 27, 2020 18:04 mike@newclarity.net (Mike Schinkel)
> On Feb 27, 2020, at 12:52 PM, Paul M. Jones <pmjones@pmjones.io> wrote: >> On Feb 27, 2020, at 11:27, Rowan Tommins collins@gmail.com> wrote: >> On Thu, 27 Feb 2020 at 17:06, Paul M. Jones <pmjones@pmjones.io> wrote:
At the risk of being the messenger that gets shot, I feel like that horse is dead. And beating it more won't revive it, or make it any more dead. JMTCW. -Mike
  108778
February 26, 2020 21:46 mike@newclarity.net (Mike Schinkel)
> On Feb 26, 2020, at 1:55 PM, Rowan Tommins collins@gmail.com> wrote: > > On Wed, 26 Feb 2020 at 16:42, Paul M. Jones <pmjones@pmjones.io> wrote: > >> Your presumption is correct! And your point on trying for better names is >> well-taken -- though I think these are "expected" names, based on my >> research into existing implementations. The most-common names are ... >> >> - the word "files" for unparsed or unmodified $_FILES values, leading me >> to think $files is well-understood >> >> - the words "upload(s)", "fileUpload(s)", or "uploadedFile(s)" for parsed, >> transformed, or restructured $_FILES values, leading me to think $uploads >> is well-understood >> > > > That's a reasonable justification. Just to check, are there other > implementations that have both of these names side by side, or do most > implementations have one or the other, but using this naming? > > The main confusion I can see is having to remember which two of these is an > error without having to read the docs each time: > > isset( $request->files['attachment']['name'][0] ); > isset( $request->files['attachment'][0]['name'] ); > isset( $request->uploads['attachment']['name'][0] ); > isset( $request->uploads['attachment'][0]['name'] );
Here is an easy way to remember: $request->files is exactly like $_FILES (and if you can't remember that, blame PHP, not the RFC) $request->uploads is therefore new, and since it is new it follows a reasonable collection-list-item structure (as opposed to an unreasonable collection-item-list structure that PHP implemented in $_FILES.) So from those rules: // Don't use, it's the old way of doing things, unless you are just replacing a reference to $_FILES then then it's a non-issue. isset( $request->files['attachment']['name'][0] ); // Don't use, it's the old way of doing things, unless you are just replacing a reference to $_FILES then then it's a non-issue. isset( $request->files['attachment'][0]['name'] ); //Don't use. Not a reasonable collection-list-item structure. Why would "they" create a new API with a parallel array structure?!? isset( $request->uploads['attachment']['name'][0] ); // This one is golden! It's clearly new because of now $_UPLOADS existing, and it follows a reasonable collection-list-item structure isset( $request->uploads['attachment'][0]['name'] ); #jmtcw -Mike