Hello Internals,

I've been meaning to write up a full-blown RFC for introducing a new
standardized HTTP interface for PHP core for some time now. I figure now
with PHP 7 on the road map this might be a good time to start this
discussion since it involves breaking some backwards compatibility that may
have been out of the question in PHP 5.

I've started a draft RFC, but please be patient as this is a working in
progress, here https://wiki.php.net/rfc/http-interface on the wiki.

The point here is to allow users to implement their own HttpRequest and
HttpResponse classes that can deal directly with the raw request/response
messages in any way the user deems fit. This alleviates cases like "what
about when I want to have $_PUT or $_DELETE" and removes the ambiguity of
the $_POST, $_GET superglobals to a more conforming way of handling the
messages.

Since it's an interface, it only dictates the facilitation of PHP's
built-in functionality and the user's desired implementation, but no the
implementation itself. To remove all confusion, consider the way an HTTP
message actually looks.

GET /foo?bar=1 HTTP/1.1
Host: foobar.com

baz=2

Instead of treating this with current $_GET, $_POST, let's consider for a
moment how we might treat it in an HttpRequest object:

If the HttpRequest class implements an HttpParameters object that parses
and treats the entire HTTP request line as a string of parameters we could
accomplish the following...

var_dump(HttpRequest::$parameters->bar); // int(1)
var_dump((string) HttpRequest::$parameters); // string(6)"?bar=1"

Now consider how the body can be treated...

echo HttpRequest::$body; // baz=2
echo HttpRequest::$body->baz; // 2

Since the HttpRequest object can lazily parse the body it can also lazily
apply custom filters directly to the request variables and parameters...

For example, say you wish to treat baz only as an integer? This can be
easily accomplished by setting the filters directly in the HttpRequest
object and upon access the filter is directly applied to chosen variables.
This also alleviates the need to worry about overwriting superglobal
variables or having to copy from them. So from an efficiency stand-point
this approach works much better. It also allows you to separate clearly
between HTTP request parameters and HTTP request body as well as the HTTP
request method. Since the request object should be capable of handling
callbacks for each method to apply different sets of filters or rules on
treating the request body given different request methods this could prove
a lot more useful than existing techniques applied directly in PHP with
php://input, for example.

We don't need to copy the internal stream and we don't need to modify or
copy superglobals around to different parts of our code.

I'm in the process of writing up a cleaner implementation to introduce in
the RFC, but in the mean time I'd like to open up to discussion and see
what others think or how they feel we might approach this problem more
cleanly.

Thanks,
Sherif

Reply via email to