Sunday, June 19, 2011

PHP GET & POST precedence

First of all, it is a very bad practice that a URL contains a parameter which has the same name with a parameter in a POST form. For example:

<form method="POST" action="submit.php?action=doThis">
...
...
<input type="hidden" name="action" value="doThat">
</form>

You shall always avoid this.

But here, we are not talking about good practice in development. We are just looking into this issue form the technology point of view.

So, in case the above situation happened, what would be the value of "action"?

If we var_dump($_GET['action']), we can find the value is 'doThis'. If we var_dump($_POST['action']), the value is 'doThat'.

So far so good, no confusion. But what if we are using $_REQUEST['action']? It turns out that if we var_dump($_REQUEST['action']), we will get 'doThat'! The POST one takes the precedence.

In PHP, By default, POST has higher priority than GET. We can change that in php.ini if we want. Take PHP5.3.3's php.ini as an example. We can find a directive request_order = "GP". The document states "This directive determines which super global data (G,P,C,E & S) should be registered into the super global array REQUEST. If so, it also determines the order in which that data is registered".

G = GET, P = POST, C = COOKIE, E=ENV, S = SERVER.

So request_order = "GP" means GET data will be registered into the $_REQUEST array first, and then POST. So POST data will override the GET data in $_REQUEST.

You may also want to have a look at variables_order = "GPCS". Just check it through in your php.ini.

So how to avoid this potential confusion? For me, the only correct and clean solution is don't ever try this bad practice in your development. Some developers may bring another suggestion: don't use $_REQUEST. Well, personally, i don't completely agree with this suggestion, but i think i should talk about this issue in another post. 

3 comments: