Skip to content

Instantly share code, notes, and snippets.

@rdlowrey
Created June 22, 2012 15:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rdlowrey/2973301 to your computer and use it in GitHub Desktop.
Save rdlowrey/2973301 to your computer and use it in GitHub Desktop.
Name/Value Parameters in PHP's HTTP Request Modeling

Name/Value Parameters in PHP's HTTP Request Modeling

For many PHP devs, their first experience with HTTP request parameters comes in the form of the $_GET and $_POST superglobals. These globally accessible arrays are an easily digestable abstraction of the HTTP spec. Indeed, for basic applications operating only in the context of common browser user-agents, these eminently accessible parameter collections work well.

But there are some significant problems with $_GET and $_POST under the surface:

  1. Superglobal use violates basic OOP principles. The name superglobal in itself is a big red flag. We aren't just talking about global variables, these bad boys are SUPER global variables. And though one of PHP's major strengths is first-class HTTP access, we should still avoid littering OO code with globals (and superglobals). Effective OO code should never directly access the $_GET and $_POST superglobals.

  2. The names $_GET and $_POST are actually quite misleading as their functionality relates to the HTTP specification. While it's not the job of PHP to teach developers the nuances of HTTP, it should at least endeavor to avoid misrepresenting how HTTP requests work.

Why the names $_GET and $_POST are misleading

You mean $_GET is available if the HTTP method isn't GET?

According to section 3.2.2 of the HTTP specification, a valid URL may contain a query string regardless of the HTTP method verb used to access it. This means that query parameters are part of the full request URL and are completely unrelated to the HTTP GET method. As a result, PHP's $_GET superglobal can be populated for POST, PUT, DELETE or any other HTTP request method. A much more accurate name for an array of parsed query parameters, then, might be something like $_QUERY or $_QUERY_PARAMETERS. $_GET has no correlation to the HTTP GET method, and naming it as if it does is patently misleading.

$_POST is insufficient for RESTful HTTP request handling

$_POST wasn't so bad in 1998 when the web was mostly thought of in terms of browser user-agents that submitted forms via GET or POST. But PHP's $_POST becomes a component of a larger leaky abstraction in a world where RESTful APIs deal in HTTP methods like PUT and OPTIONS. To understand why this is so, we need to understand where $_POST data comes from.

The HTTP entity-body

The HTTP specification describes the entity-body as follows (rfc2616-sec7.2):

Request and Response messages MAY transfer an entity if not otherwise restricted by the request method or response status code. An entity consists of entity-header fields and an entity-body, although some responses will only include the entity-headers.

When a user-agent (browser) submits a form via POST, the browser encodes the form values and packages them in the standard key-value format:

formVar1=myValue&formVar2=myOtherValue

This string of parameters is sent in the entity-body portion of the HTTP message. As a convenience, PHP parses this entity-body for you when POST forms are submitted and makes the submitted values easily accessible in the $_POST superglobal.

What's wrong with that?

The problem here is that POST isn't the only HTTP method for which an entity-body is appropriate. PUT requests require an entity-body and the HTTP OPTIONS method also optionally allows entity-body data. $_POST is therefore an incomplete representation of the larger concept of entity-body parameters. It's only useful as a convenience wrapper for a very specific operation.

Because the same method could be used to parse PUT parameters (but isn't by PHP), $_POST would be much more appropriately named something like $_ENTITY_BODY_PARAMETERS. This would apparently be too confusing (or too long) for people to understand. Unfortunately, the result is a generation of PHP developers who don't understand how HTTP works because PHP tells them everything is GET and POST data.

@Lewiscowles1986
Copy link

Is there a patch to exclude / de-activate the superglobals for PHP, or is unset still the preferred method?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment