Is Using Superglobals Directly Good or Bad in PHP

Is using superglobals directly good or bad in PHP?

I do like to wrap $_SESSION, $_POST, $_GET, and $_COOKIE into OOP structures.

I use this method to centralize code that handles sanitation and validation, all of the necessary isset () checks, nonces, setcookie parameters, etc. It also allows client code to be more readable (and gives me the illusion that it's more maintainable).

It may be difficult to enforce use of this kind of structure, especially if there are multiple coders. With $_GET, $_POST, and $_COOKIE (I believe), your initialization code can copy the data, then destroy the superglobal. Maybe a clever destructor could make this possible with $_SESSION (wipe $_SESSION on load, write it back in the destructor), though I haven't tried.

I don't usually use any of these enforcement techniques, though. After getting used to it, seeing $_SESSION in code outside the session class just looks strange, and I mostly work solo.

EDIT
Here's some sample client code, in case it helps somebody. I'm sure looking at any of the major frameworks would give you better ideas...

$post = Post::load ();  
$post->numeric ('member_age');
$post->email ('member_email');
$post->match ('/regex/','member_field');
$post->required ('member_first_name','member_email');
$post->inSet ('member_status',array('unemployed','retired','part-time','full-time'));
$post->money ('member_salary');
$post->register ('member_last_name'); // no specific requirements, but we want access
if ($post->isValid())
{
// do good stuff
$firstName = $post->member_first_name;
}
else
{
// do error stuff
}

Post and its friends all derive from a base class that implements the core validation code, adding their own specific functionality like form tokens, session cookie configuration, whatever.

Internally, the class holds a collection of valid data that's extracted from $_POST as the validation methods are called, then returns them as properties using a magic __get method. Failed fields can't be accessed this way. My validation methods (except required) don't fail on empty fields, and many of them use func_get_args to allow them to operate on multiple fields at once. Some of the methods (like money) automatically translate the data into custom value types.

In the error case, I have a way to transform the data into a format that can be saved in the session and used to pre-populate the form and highlight errors after redirecting to the original form.

One way to improve on this would be to store the validation info in a Form class that's used to render the form and power client-side validation, as well as cleaning the data after submission.

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

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...

How to access superglobals in correct way?

As the hint says, accessing the superglobals violates the encapsulation principle

A really basic approach would be:

class SessionObject
{
public $vars;

public function __construct() {
$this->vars = &$_SESSION; //this will still trigger a phpmd warning
}
}

$session = new SessionObject();
$session->vars['value'] = "newValue";

You can also have a look to the Symfony HttpFoundation Component for a full-fledged implementation

Do you consider it bad form in PHP to access super globals within class methods?

I wouldn't say there is a straight yes or no answer to this one. What the idea (with all superglobals $_GET $_POST $_SESSION) is that you are asking for data that sits in your entire application, and not local to the scope you are asking for.

What can happen with these superglobals is that what if they change somewhere for whatever reason just before or (god forbid) during the execution of your function. That can turn out to be a very annoying bug to reproduce.

So I would say it is bad form.

Is it wise to write superglobal $_POST directly to a database?

That is a really bad idea, because then any extra POST fields that don't correspond to columns would break the query. Your own code uses $_POST['type'] to determine which table you're updating, which would break as well unless you unset it beforehand.

Also, you are not doing any validation on the data that is actually being sent to the DB. Changing your own name/permissions to Admin? Sure. Changing another user's email to your own? Go ahead. Making your account balance +100,000$? No problem. Mark a product as "price $1"? Yup.

It would be a lot smarter to have some kind of Active Record. If you're writing a larger application, look into a framework such as Yii or Cake PHP, they come with such functionality built in.


Aside from that: Please stop writing new code with the ancient mysql_* functions. They are no longer maintained and community has begun the deprecation process. Instead you should learn about prepared statements and use either PDO or MySQLi. If you care to learn, here is a quite good PDO-related tutorial.

PHP - is it safe to store anything in the $_SESSION superglobal?

It all depends on what you mean by "security". There is no abstract notion of "being secure". You can only be secure against specific threats. (This is called your "threat model".) If you don't say what you want to be secure against, it's impossible to say whether your solution is good or not. There's certainly no guarantee that zombies won't come and eat your site users when they log in to your site!

That said, session variables are inaccessible through the web server, so they form part of the opaque state of your web application which the user cannot see or exploit directly.

On the other hand, there are numerous avenues of attack that allow for leaking, stealing or abuse: If the session cookie is stolen, someone else can take over the session (and perhaps launch the nuke); this is an entirely common Starbucks-type scenario. Another vulnerability lies on the server itself: If the session data is stored in a file that is readable by other users, say on a shared host, then it is possible that others may obtain the session ID and the session data behind your back, by reading them directly from the server's disk.

It all depends! Probably best not to write your nuke strike management app in PHP on a shared host...

Are global variables in PHP considered bad practice? If so, why?

When people talk about global variables in other languages it means something different to what it does in PHP. That's because variables aren't really global in PHP. The scope of a typical PHP program is one HTTP request. Session variables actually have a wider scope than PHP "global" variables because they typically encompass many HTTP requests.

Often (always?) you can call member functions in methods like preg_replace_callback() like this:

preg_replace_callback('!pattern!', array($obj, 'method'), $str);

See callbacks for more.

The point is that objects have been bolted onto PHP and in some ways lead to some awkwardness.

Don't concern yourself overly with applying standards or constructs from different languages to PHP. Another common pitfall is trying to turn PHP into a pure OOP language by sticking object models on top of everything.

Like anything else, use "global" variables, procedural code, a particular framework and OOP because it makes sense, solves a problem, reduces the amount of code you need to write or makes it more maintainable and easier to understand, not because you think you should.

Good explaining of using PHP superglobal arrays and while/foreach loops

Whenever you escape stuff, the context is essential.

If you're inserting into a database using the (now outdated) mysql_ functions, you use mysql_real_escape_string.

If you're outputting to the browser as part of an HTML document, you use htmlspecialchars.

If you're passing user input as a parameter to a shell function, you use escapeshellarg.

If you're dropping user input into a JavaScript variable, you use json_encode.

The point I'm trying to make here is that there is no panacea to escaping user input. It all depends on exactly what you're using it for.


Context is also important for loops. If you're iterating over an indexed array, you'd use a for loop. If you're iterating over an associative (key=>value) array, you use foreach. If you're looping on a condition, use while. All loop types have their own purpose.



Related Topics



Leave a reply



Submit