On Tue, Jun 27, 2023, at 3:26 PM, Stephen Reay wrote: >> On 28 Jun 2023, at 02:53, Ben Ramsey <[email protected]> wrote: >> >>> On Jun 27, 2023, at 04:01, Ilija Tovilo <[email protected]> wrote: >>> >>> Hi Ben, Hi Rowan >>> >>> On Mon, Jun 26, 2023 at 8:55 PM Ben Ramsey <[email protected]> wrote: >>>> >>>>> On Jun 20, 2023, at 06:06, Rowan Tommins <[email protected]> wrote: >>>>> >>>>> On Tue, 20 Jun 2023 at 10:25, Ilija Tovilo <[email protected]> wrote: >>>>> >>>>>> Introduce a new function (currently named populate_post_data()) to >>>>>> read the input stream and populate the $_POST and $_FILES >>>>>> superglobals. >>>>> >>>>> How about "request_form_populate_globals"? >>> >>> The word "form" seems a bit out of place (even though it appears in >>> both multipart/form-data and application/x-www-form-urlencoded), >>> because this function is mainly targeted at PUT/PATCH requests for >>> REST APIs. Maybe request_body_populate_globals? >>> >>>> Another option for the name: `populate_multipart_form_data()`. >>> >>> I avoided the term "multipart" because the function technically also >>> works for application/x-www-form-urlencoded requests. It's less >>> necessary for the reasons outlined in my previous email, but it would >>> allow for consistent handling of such requests for all HTTP methods. >>> >>> Some people on GitHub voiced that they would prefer an INI setting. >>> Therefore I will create an RFC accordingly. >> >> >> I know this issue comes up enough because it’s confusing to developers that >> there’s not a `$_PUT`, etc., but I’m not a fan of introducing something new >> that populates globals. >> >> While I’ve never used `application/x-www-form-urlencoded` data for `PUT` >> requests (because I don’t think it’s a proper content-type for the semantics >> of `PUT`), I do see how this content-type could be used with `PATCH`, and I >> also don’t want to rule-out use cases of it for `PUT` or any other HTTP >> method. >> >> In the past, I’ve used something like the following to solve this: >> >> parse_str(file_get_contents('php://input'), $data); >> >> I haven’t looked up how any of the frameworks solve this, but I would be >> willing to bet they also do something similar. >> >> Rather than implementing functionality to populate globals, would you be >> interested in introducing some new HTTP request functions. Something like: >> >> http_request_body(): string >> http_parse_query(string $queryString): array >> >> `http_request_body()` would return the raw body and would be the equivalent >> of calling `file_get_contents('php://input')`. Of special note is that it >> should _always_ return the raw body, even if `$_POST` is populated, for the >> sake of consistency and reducing confusion. >> >> `http_parse_query()` would be the opposite of `http_build_query()` and would >> return a value instead of requiring a reference parameter, like >> `parse_str()`. >> >> While these don’t address the confusion users face by not having a `$_PUT` >> superglobal, I’d prefer not to overload the superglobals. Maybe we can >> update the documentation to encourage use of these new functions instead of >> the superglobals? >> >> We also might want to introduce something like `http_query_string(): string` >> that always returns the raw query string, instead of requiring use of the >> superglobal `$_SERVER['QUERY_STRING']`. >> >> Cheers, >> Ben > > > As a userland/library developer I *much* prefer this approach, but > *please* also include `http_uploads()` (name/signature TBD), returning > an array of file uploads using a structure akin to what $_POST (or > http_parse_query) gives, based on the field name, rather than the > current scenario where the presence of square brackets radically > changes the structure of the $_FILES array. > > My initial thought was that perhaps the leaf entities in said array > could be a subclass of SplFileInfo referencing the uploaded temporary > file, with additional read-only properties for the extra upload-related > attributes - but really the important thing is just having a sane, > consistent structure. Having an object rather than an array with > constant keys would be a nice addition, but is much less important. > > > > Cheers > > Stephen
I also like Ben's suggestion. It avoids adding more magic globals, but also is still simple and straightforward to use in an easily composable fashion. Based on the Content-Type header of the request, it would allow for: $formData = http_parse_query(http_request_body()); $jsonData = json_decode(http_request_body()); ... Whatever other body parsers. While you should probably not call it exactly like that, it means "take body string, pass to mime-appropriate body parser" is an easy pattern, and one that can also be easily mocked for testing. --Larry Garfield -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
