Should I Use PHP Superglobals or Filter Input to Retrieve $_GET data?
Asked Answered
E

7

10

I really hate global variables - maybe its the C# programmer in me but when I'm working in PHP I grit my teeth every time I have to do something like this:

$strUsername = $_GET['username'];

Yes, I'm grossly oversimplifying it and yes yes I sanitize all of this properly. In fact, for the framework that I built, all of the superglobals are grabbed almost at the beginning of execution and are dependency-injected from there on out.

I ran across this function in the PHP manual (you truly learn something new every day): filter_input_array().

So now, technically, I can do this instead of grabbing everything from the GET superglobal:

$GETdata = filter_input_array(INPUT_GET);

.... and so on and so forth with the others like POST, REQUEST, etc. My question is: should I use filter_input_array and so avoid the scourge of superglobals, or is there some reason to stick with them and forget about using the filter_input functions? What is everyone else's experience with this?

EDIT: I forgot one thing - the filter_input functions are blind to any script-level modifications you make to the superglobals so if I do: $_GET['cheese'] = 'puff'; trying to do filter_input(INPUT_GET, 'cheese'); later will return null. This is fine since I dependency inject everything but it could catch somebody off guard later, if they are unaware.

Ezekielezell answered 14/4, 2011 at 15:40 Comment(7)
From a performance standpoint, do you really want to filter the input every time you need them? e.g. You call foo() and sanitize them there, but what if bar() needs them as well? Do you re-sanitize?Lemoine
If you don't need any filtering - why to bother with 1 pointless function call?Skillet
Superglobals exist for a reason. You might be wondering what they're good for, but until you run into a problem where they're actually incredibly useful - you'll probably frown upon them and try to avoid them by creating wrappers that create yet another array.Hoarding
isn't "scourge of superglobals" a little dramatic? :]Diakinesis
@BradChristie & @Skillet - My question isn't really about filtering or sanitization or validation or anything. Its about that first, initial grab of GET and POST data that are foreverafter dependency injected. Models handle their own validation and filtering, and views handle sanitizing output.Ezekielezell
@Jarrod: wrap your $_GET and $_POST with some Request class and become happy then ;-)Skillet
possible duplicate of Is using superglobals directly good or bad in PHP?Plugboard
P
9

Using filter_input_array is still using superglobals because it's still getting its data from one of the superglobal arrays.

There's nothing wrong with getting your data from one of these arrays, its really the only way to get the data actually. You just have to make sure you escape it for whatever you're using it in.

htmlentities for html, prepared string for pdo, mysql_real_escape_String for mysql_ functions etc...

Phosphoresce answered 14/4, 2011 at 15:45 Comment(1)
Not true. filter_input_array(INPUT_SERVER) will not return REQUEST_TIME or REQUEST_TIME_FLOAT. Thus, filter_input_array() is getting values without using the superglobals. The real question is if you are creating a Request object, should you seed it with $_SERVER or filter_input_array(). Ultimately, wrapping the values derived from superglobals and functions is easier, but there is another way: php://inputThorvald
P
5

Why are global variables bad?

The common argument is, because you introduce unnesseccary dependencies to an external state.

Your solution does not prevent that, it only hides it.

A better solution would be, imho, to provide $_GET as an argument, as in

function myController($get) {
   $user = Model::get_user($get['userid']);
   render_view('user.html', $user);
}

myController($_GET)

as that adresses the reason why global variables are considered bad.

Puce answered 14/4, 2011 at 15:45 Comment(4)
Yep, and this is called dependency injection. To improve your code a little it could be nice to rename $get to something like $request.Skillet
i just wrote it down, i dont even remember PHPs naming conventions since i left it for sweet python :). maybe also an interesting term to search: law of demeter.Puce
I mentioned in the original question that everything is dependency injected. Nothing steams me more than running across a floater $_GET in the middle of a class method. And yes, I realize that I am simply hiding the problem.Ezekielezell
@jarrod - so then, why would you try to replace $_GET with an equivalent statement instead of moving said code to your superiour style used in your framework?Puce
A
3

I use PHP superglobals, but only at the library level in my Framework. This is framework all controllers have access to the request object, which in turn access the superglobals. This allows you to write tests for your controller by making a mock request object populated with your test parameters. It's all about good OO design and good design patterns.

Accessing the superglobals directly everywhere without any abstraction in place is an anti-pattern.

Autobus answered 14/4, 2011 at 15:48 Comment(0)
M
1

I really hate those global variables as well. I would definitely use filter_input_array and use the array whenever needed. This solves a lot of global-related bugs and prevents you from spending hours debugging these hard-to-find globals.

I think that filter_input_array is the wtg!

Michale answered 14/4, 2011 at 15:45 Comment(3)
besides hatred, whats the point? in what way is a statmement that is equivalent to a global variable better than the global variablePuce
in this case you wouln't pollute your main scope with cluttered global variables, replacing it for only one global, which minimizes code complexity. Anyway, i like your approach.Michale
Be careful about $_SERVER and filter_input_array(INPUT_SERVER).They do not return the same output.Thorvald
L
1

I don't think someone knows perfect answer :)

Sometime I use it, sometimes I get data just like $_GET['data'], sometimes I even use import_request_variables().

On some project I have special Class, that process POST, GET, REQUEST and do something like this: POST::getValue('username') or GET::getValue('session_id') or COOKIE::getValue('last_time_seen')...

Lotze answered 14/4, 2011 at 15:48 Comment(6)
Unfortunately import_request_variables() is now deprecated, although you can still use extract($_GET) to do the same thing.Therapeutics
not exactly, import_request_variables operated on $_POST, $_GET and $_COOKIE arrays.Lotze
You're right, extract($_REQUEST) would work though.Therapeutics
Not really. What if you have $_GET['city'] = 1;, $_POST['city'] = 2; and $_COOKIE['city] = 3; ? ;)Lotze
Then the latter would override the others, just as import_request_variables would have done. The only difference is that you can choose the order in which they are imported using the $types argument.Therapeutics
Using extract() on a super global can be a bad idea from a security point of view. If you must use it, use a prefix and/or the EXTR_SKIP flag, and don't do your extraction in the global scope.Concordat
S
1

If you really don't like superglobals, why not to write your own implementation for cleaning like vB_Input_Cleaner class here?

http://members.vbulletin.com/api/

Stichometry answered 14/4, 2011 at 15:53 Comment(0)
H
0

Some years ago it was even worse, the parameter &x= in the URL appeared as global $x. Amyway, if you don't use $_GET, except in the framework, it does not exists.

Hafer answered 14/4, 2011 at 18:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.