The superglobals are a hopelessly poor abstraction. Can we stop trying to
put the proverbial gold ring in the pig's snout on this?
While a change to $_QUERY
and $_BODY
would undoubtedly be an
improvement I don't think the massive BC breaks that would result are
justified by simply improving variable names. The problem isn't
nomenclature; it's globally mutable data structures whose key-value nature
aren't a good fit for the unrestricted possibilities of HTTP. You can't
efficiently model an HTTP request with associative arrays. Period.
The other elephant in the room is that your average wordpress developer
will continue to use $_GET
and $_POST
regardless. So any improvements
that are made should be targeted at professional developers. The obvious
thing to do here is to introduce an entirely separate abstraction that can
be used by professional developers without eliminating the exceedingly
simple superglobal abstraction (hello, BC easily retained).
Something like the following would be an infinitely superior solution:
interface HttpRequest {
function getMethod();
function getContentType();
function getContentLength();
function getBody();
function getBodyStream();
function hasHeader($fieldName);
function getHeader($fieldName);
function hasFormField($fieldName);
function getFormField($fieldName);
function hasCookie($fieldName);
function getCookie($fieldName);
}
By adding a global function such as get_request()
that returns the
immutable request object you get all the functionality you could want:
- Entity body parsing (for cookies or form data) could be done JIT
- Userland code can easily typehint against the request
- No more mutability, eminently testable
- Eliminates the need for
$_GET
,$_POST
,$_COOKIE
, etc ...
This is simply an example of a much better way to model HTTP requests --
it's not a suggestion for a final implementation. But IMO if we're going to
fix this then we should really fix it and not continuously tickle the same
broken abstraction.
Some other thoughts ...
While we're at it, can we remove the quirk that existed due to
register_globals
where periods and such are replaced with underscores?
I think "fixing" this is a bad idea. You simply can't allow invalid
variable name characters as part of these keys. That's asking for trouble.
This problem is completely nullified with an immutable request object,
though.
I would strongly recommend against adding additional body parsers that
are automatically invoked based on the content type. Adding additional
parsers creates a high security risk.
Agreed. It's best to retain the thoroughly tested existing parser
functionality for things like multipart, url-encoded forms and cookies.
These can easily be reused as part of a JIT object-based solution.
Everything else should be the user's responsibility (until proven so
ubiquitous as to be useful at the language level). Manual userland parsing
should be trivial as long as the raw entity body is available.
The superglobals are a hopelessly poor abstraction. Can we stop trying to
put the proverbial gold ring in the pig's snout on this?[...]
Something like the following would be an infinitely superior solution:
interface HttpRequest {
function getMethod();
[...]
}By adding a global function such as
get_request()
that returns the
immutable request object you get all the functionality you could want:
- Entity body parsing (for cookies or form data) could be done JIT
- Userland code can easily typehint against the request
- No more mutability, eminently testable
- Eliminates the need for
$_GET
,$_POST
,$_COOKIE
, etc ...This is simply an example of a much better way to model HTTP requests --
it's not a suggestion for a final implementation. But IMO if we're going to
fix this then we should really fix it and not continuously tickle the same
broken abstraction.
While I totally agree with your point, I don't see why this needs to be
in core. This is perfectly done in userspace, even the immutable part.
The only benefit of putting that in core would be the standard-defining
part, but not much else. Plus it's not minimizing any abuse, as long as
the superglobals are still available (and I don't think renaming or
removing them would be a good idea.
Greetings,
Florian
The superglobals are a hopelessly poor abstraction. Can we stop trying to
put the proverbial gold ring in the pig's snout on this?[...]
Something like the following would be an infinitely superior solution:
interface HttpRequest {
function getMethod();
[...]
}By adding a global function such as
get_request()
that returns the
immutable request object you get all the functionality you could want:
- Entity body parsing (for cookies or form data) could be done JIT
- Userland code can easily typehint against the request
- No more mutability, eminently testable
- Eliminates the need for
$_GET
,$_POST
,$_COOKIE
, etc ...This is simply an example of a much better way to model HTTP requests --
it's not a suggestion for a final implementation. But IMO if we're going to
fix this then we should really fix it and not continuously tickle the same
broken abstraction.While I totally agree with your point, I don't see why this needs to be
in core. This is perfectly done in userspace, even the immutable part.The only benefit of putting that in core would be the standard-defining
part, but not much else. Plus it's not minimizing any abuse, as long as
the superglobals are still available (and I don't think renaming or
removing them would be a good idea.
Also mind that filter_input()
as an immutable API exists.
johannes
Daniel Lowrey wrote (on 02/10/2013):
Something like the following would be an infinitely superior solution:
interface HttpRequest {
While having a quick look for userland parsing functions earlier, I came
upon the PECL http extension, which includes this all-singing object:
http://www.php.net/manual/en/class.httprequest.php
As for this:
You can't efficiently model an HTTP request with associative arrays. Period.
The fact is that for 99% of use cases, yes you can, and developers
happily do so. PHP even allows the convenient field_name[]= and
field_name[key]= notations for building multi-dimensional arrays.
This is all a convenience wrapper, and a consistent low-level API would
be good, but alternative high-level APIs can be built from a few
fundamental building blocks (e.g. getting the basic raw request parts as
strings, parsing strings in various form encodings) without building a
whole HTTP framework into the core.
Regards,
Rowan Collins
[IMSoP]