Bitten by $_REQUEST

Total­ly unre­lat­ed to The Vam­pire Rule,1 today I got a prac­ti­cal les­son in PHP request precedence.

I’ve seen for years rec­om­men­da­tions not to use the super­glob­al $_REQUEST along with a vari­ety of expla­na­tions why to avoid it. These expla­na­tions stem from the pos­si­bil­i­ty that one could be con­fused about the source of the infor­ma­tion from $_REQUEST and end up get­ting some data oth­er than the data one expects to see. It was exact­ly this rea­son that I have been using $_REQUEST: I have been retriev­ing infor­ma­tion from a mix­ture of GET and POST sources in form sub­mis­sions. Depend­ing on con­text, I might switch the data from GET to POST or the­o­ret­i­cal­ly vice-versa.

In this project I’m try­ing to fix, there is a piece of data that in some cir­cum­stances just was­n’t get­ting saved out cor­rect. Instead anoth­er piece of data was saved in its place. I did all sorts of log­i­cal jug­gling to enforce prece­dence, because this piece of infor­ma­tion could come from mul­ti­ple places and might have some con­flicts. I know what order of prece­dence I want: get the data out of the cook­ie for con­ve­nience, but if a form sets that val­ue, take the val­ue set explic­it­ly by the form. And if there is a URL-encod­ed form, use that over all oth­er options.

Why would I want this? Well, I’d like to have the val­ue set and then if the user does some­thing crazy like go to anoth­er page and then type the URL for the site back in, I want the data to still be set for that user. Also, when test­ing (or for the con­ve­nience of being able to send some­one a URL with the spe­cif­ic val­ue set) I’d like to man­u­al­ly just type the val­ue to the end of the URL. Easy peasy. Convenient.

Which means the order of prece­dence I want is: GPC or «GET, POST, COOKIE» In all the places where I set this par­tic­u­lar val­ue, I was very clear about where I was get­ting each and which to choose in the case of conflict.

Except one place where I set the val­ue with, you guessed it, $_REQUEST.

This pos­si­bly should have been an easy prob­lem to diag­nose. I knew about this, but from doc­u­men­ta­tion and online dis­cus­sions I knew that in PHP 5.3 and new­er that the default set­ting for request_order is GP. Which means the cook­ie is nev­er looked at. That’s not GPC but that’s per­fect­ly OK. I’m more than hap­py to explic­it­ly get the cook­ie data only when I explic­it­ly ask for it. The web­site with this thorny issue is run­ning PHP 5.3, so this kind of prece­dence could­n’t pos­si­bly be the prob­lem. Right?

Of course not.

See, PHP 5.3 has a default con­fig­u­ra­tion that it’s shipped with that includes the line:

request_order = GP

How­ev­er, I’m not run­ning a default con­fig­u­ra­tion. The PHP was upgrad­ed some time ago. And request_order = GP is not a glob­al default in PHP 5.3, it’s a line includ­ed in the default con­fig­u­ra­tion file. Not the same thing. I had no request_order direc­tive at all. As it says clear­ly in the doc­u­men­ta­tion if request_order is not set, the val­ue defaults to what­ev­er is set for variables_order. variables_order is EGPCS which means… well, it’s not GP, let’s leave it at that.

Am I going to stop using $_REQUEST? No, I’m not. It’s still a handy way for me to get at the data I want. In fact, now that I know I can explic­it­ly set the val­ue it might even be more handy. But I now have a fin­er appre­ci­a­tion for the rea­son so many peo­ple sug­gest not to use it.

  1. The Vam­pire Rule states that one must be invit­ed in by one’s vic­tim before com­menc­ing any unpleas­ant­ness. 

Leave a Reply