tags:

views:

111

answers:

5

I am using PHP

  1. to implement an HTML form and
  2. for validation of the data submitted by the form.

There are two scripts. In order for the second script to know about values assigned by the first, I am using a POST method with the following code:

foreach (${"_".$_SERVER["REQUEST_METHOD"]} as $k => $v) $$k = $v;

to retrieve each of the (key => value) elements of the POST (or GET) associative array and create variables with those names and values.

I don't remember where I found this code, but I was impressed with it, once I worked out how it does its job.

It works well, but I know if I go back to it in a few months, I won't remember how it works unless I add extensive comments, and I'd prefer to use something I can immediately understand and which fits well with my non-idiomatic style.

Does anyone have any suggestions?

CONCLUSION:

I like the idea of extract() and I'll probably use it. Thankyou all.

I should explain perhaps why some of the points raised in the answers below don't bother me:

  • The form is only visible on a Company intranet. The users have trouble figuring out which button to click on, much less 'how to attack it?'
  • The users enter simple values in the form fields: x and y co-ordinates, measurements, lot numbers. Validation is straightforward. If it doesn't work, I'm on site, they'll come and ask me why.
  • The values end up in a DB which only my apps access. I don't allow anything which might constitute SQL injection.
  • I don't have to worry about other developers. I'm the only developer and I'm just trying to overcome the corporate culture of using bloated Windows applications for everything when simple web apps will do. I had a heated discussion with a senior engineer the other day about why I use a MySQL database, when you can do anything with Access & Excel.

But I shouldn't get myself started ...

+4  A: 

Doing this is a potential security risk, as an attacker can easily change other variables.

Have you considered just using the $_REQUEST superglobal?

Charlie Somerville
Well, actually, this is for an intranet behind a pretty good firewall ... so security is not a big concern. Something to bear in mind for the future, perhaps. I'll look into the $_REQUEST superglobal, thanks.
pavium
@pavium, The threat is not from outside, but is from people inside the intranet i.e. your own employees etc.
Alec Smart
A: 

Yes, there's a less idiomatic way to do this. You can enable the "register_globals" setting from php.ini.

However, before you do, make sure you google for "php register_globals security" to get a hint as to why it might not be such a brilliant idea.

oggy
register_globals will also be removed in PHP 6, so while its release is a ways off (and PHP 5 will still be available) it can't be counted on indefinitely.
GApple
I'm already aware thar register_globals is not a good idea, and I wouldn't dream of enabling it. Thanks, anyway
pavium
keep in mind that extracting GET and POST variables to the global name space manually can be just as bad as doing it automatically through register_globals. Worse, if not every developer knows about it and doesn't then take precautions.
GApple
So you wouldn't dream of enabling the register_globals setting, yet you're looking for a way to write code that does the exact same thing as the said setting? I sense a contradiction in there...
oggy
+3  A: 

wrong way. just use:

extract($_POST);
or
extract($_GET);
Sergei
Ah! I was hoping there was something in the PHP function reference I hadn't heard of. extract() seems like a good function for my purposes.
pavium
+3  A: 

extracting request vars is not the best practice security-wise, to say the least...

with that in mind, here's some code:

<?php    
// $req = ${"_".$_SERVER["REQUEST_METHOD"]}
if ($_SERVER["REQUEST_METHOD"] == 'GET') {
    $req = $_GET;
else {
    $req = $_POST;
}

extract($req);
?>

or simply:

<?php 
extract($_REQUEST);
?>

Do check out the documentation page for extract, you can add extra options that could help minimizing security risks..

jcinacio
There seems to be a convergence of opinion on extract(). I'll look into the extra options because, although security is not a concern in my application, I know I shouldn't get into the habit of ignoring it. Thanks jcinacio
pavium
extract($_POST + $_GET); // $_REQUEST also has cookies
Kamil Szot
yes, $_REQUEST includes cookies - thats the reason for my first (longer) example, as cookies aren't in the original OP code.
jcinacio
A: 

Generally speaking it's not good to rely on what's sent to you this way. A As suggested by others, use extract() if this is really the way you want to go but I would suggest this instead:

Each script that is a form should have a list of fields that it accepts like:

$fields = array('name', 'age', 'city');

And then do:

$form = array();
foreach ($fields as $field) {
  $form[$field] = $_POST[$field];
}

If you simply create global variables based on whatever the client decided to send you, you may inadvertently be overwriting something you expect to be there but is replaced with arbitrary values from the client. This could create a vulnerability. It's a safer practice to only accept what you expect and nothing more.

cletus