My PHP script processes some POST variables.
Instead of manually naming each variable
$name = $_POST['name'];
$email = $_POST['account'];
I'd like my script to grab all the variable names from the $_POST array and automatically create variables with those names, e.g. (not code, just illustrating the principle)
foreach ($_POST as $name => $value) {
$[$name] = $value;
}
Is something like that possible?
You can use the extract function for this. But there is a risk, because you cannot know what data is posted, and it will create or overwrite variables in the scope in which you call it, possibly leading to unexpected behaviour.
You can partially counter this, using one of the flags for extract, for instance:
extract($_POST, EXTR_SKIP);
Anyway, make sure to read the two warnings (red block) on the documentation page of this function. And of course, the same warning applies when you do this using your own foreach loop, so answers suggesting that are no more secure.
There is extract function in php:
extract($_POST);
This is a very bad idea because it allows a user to create any variable in your PHP script (within the scope that it this code is used). Take for example if you have a $debugging flag:
$debugging = false;
foreach ($_POST as $name => $value) {
$$name = $value;
}
// some time later, we do a query and output the SQL if debugging
if($debugging){
echo $sql;
}
What if a malicious user submitted an input called debugging with a value of 1? Your debugging flag would be changed and the user could see sensitive debug data.
Try this (which is a bad practice):
foreach ($_POST as $name => $value) {
$$name = $value;
}
You can do this with variable variables as follows:
foreach ($_POST as $name => $value) {
$$name = $value;
}
You can also use the following format if you want to muck about with the variable names some more:
foreach ($_POST as $name => $value) {
${$name.'_1'} = $value;
}
There are comments here saying don't use variable variables - mainly because they are hard as heck to troubleshoot, make it damn hard for others to read your code and will (for the most part) create more headaches than they solve.
Related
I have a large HTML form posting many fields to a PHP page. I'm assigning all those fields to PHP variables one by one. Is there a way to put to create a function to auto assign the POST value to a PHP variable?
This is my code now:
if (!empty($_POST["x"])) {
$x = clean_post($_POST["x"]); }
if (!empty($_POST["y"])) {
$y = clean_post($_POST["y"]);
}?>
Thanks!
You can do this using the array_keys() function and a foreach-loop like this:
foreach (array_keys($_POST) as $key) {
${$key} = $_POST[$key];
}
But why not use the $_POST array in the first place?
Yes, but it's a rubbish idea. They actually had this in PHP, but removed it. It was called register_globals. So for instance, $_POST['name'] would automatically have $name created.
If you insist on this terrible idea, you should be able to do it like this:
foreach ($_POST as $key => $value) {
$$key = $value;
}
Don't do it though! Read this for more info https://secure.php.net/manual/en/security.globals.php
I'm posting 20 results from a form, to be used on the next page, is there a quick foreach way of posting:
$UserID1 = $_POST['UserID1'];
Where the ID changes each time rather than listing it 20 odd times? I thought a foreach statement, but i'm not too sure where to begin with it?
You can use extract():
extract($_POST);
echo $UserID1; // This now works
This is not considered a good programming practice but will do what you want.
The other answers will do the job just fine, however they introduce security issues.
Code such as:
foreach($_POST as $key => $value){
$$key = $value; //Assign the value to a variable named after $key
}
Allows me to post any form field I wish to your page and alter any variables value, for example, say you have code something like this elsewhere:
if ($validation) { // Do something }
Then I am able to post a form field named validation with a value of 1 and manipulate your code as that would assign a variable called $validation to a value of my choosing.
Using that code to assign variables from all your $_POST values automatically, is the same as using register_globals which was deprecated due to it's blatent security issues. See: http://www.php.net/manual/en/security.globals.php
If you must do this, you must check that the posted values are something that you expect. For example, check for the existance of UserID. This will only allow the creation of variables if they begin with UserID:
foreach($_POST as $key => $value) {
if (substr($key, 0, 6) == 'UserID') {
$$key = $value; //Assign the value to a variable named after $key
}
}
This will check for $_POST['UserID1'] and create $UserID1 and $_POST['UserID2'] and create $UserID2...
foreach($_POST as $key => $value){
$$key = $value; //Assign the value to a variable named after $key
}
I have the following code:
if(isset($_SESSION["spgrund"])) {
$spgrund = $_SESSION["spgrund"];
}else{
$spgrund = '';
}
This code is repeated about 20 times for each session variable. How can I make a loop out of it?
foreach($_SESSION as $key => $value){
$$key = $value;
}
I think that should work. But I get undefined variable error messages. Can't I use such a loop?
What you actually try to achieve is already available in PHP, the extractÂDocs function:
extract($_SESSION);
From it's documentation:
Import variables from an array into the current symbol table.
Checks each key to see whether it has a valid variable name. It also checks for collisions with existing variables in the symbol table.
You would still need look for undefined variables however. Probably you should define them first?
foreach($_SESSION as $key => $value)
{
$$key = $value;
}
you missed the $ for value
I was checking my script for vulnerabilities and was shocked the way i used to do in the past which is extremely insecure:
foreach ($_GET as $key => $value){
$$key = $value;
}
or shorter
extract( $_GET );
I altered with firebug some POST/GET variables to match a name i used in my script. they can be overwritten if the name would be guessed correctly.
So i thought i had to do it individually naming like this:
$allowed_vars =
$allowed_vars = array("time","hotfile","netload","megaupload","user","pfda","xyz","sara","amount_needed");
foreach ($_GET as $key => $value)
{
if (in_array($key,$allowed_vars))
{
$$key = $value;
}
}
This way saves some time than naming them individually.
What kind of automation have to be used for this?
I don't use any automatism of the kind.
I see no point in assigning request variables to global variables automatically.
If it's one or two variables, I could deal with them manually.
If there are more, I'd rather keep them as array members for the convenient handling.
Yet I am using some sort of whitelisting approach similar to yours.
but not to create global variables out of POST data but to add that data into SQL query.
Like in this simple helper function to produce SET statement:
function dbSet($fields) {
$set='';
foreach ($fields as $field) {
if (isset($_POST[$field])) {
$set.="`$field`='".mysql_real_escape_string($_POST[$field])."', ";
}
}
return substr($set, 0, -2);
}
$id = intval($_POST['id']);
$fields = explode(" ","name surname lastname address zip fax phone");
$query = "UPDATE $table SET ".dbSet($fields)." stamp=NOW() WHERE id=$id";
You can save even more time by not extrating them at all. Just use them from the $_GET array. The advantages of this are not just avoiding collision with script variables (or worse) but also that you don't have to update that "automatism" when you add request parameters.
When I am working with POST data, as from a form, I often process each explicitly:
$data = array();
$data['field1'] = someSaniFunction($_POST['field1']);
$data['field2'] = someOtherFunction($_POST['field2']);
...
In this way I ensure that each field is properly handled, and only the fields I expect are touched.
In my experience, you shouldn't transform data in the $_REQUEST array into variables using $$ as it gives the possibility of overwriting variables held within the current scope.
Instead, you should consider having a request object or array in which you filter the data and only access named variables that you require. This way, you do not have to keep extending your allowed variable names and still maintain security.
The ZF for example has a request object, and they recommend using a input filter when working on this data:
http://framework.zend.com/manual/en/zend.filter.input.html
You can use the extract function in a more secure way:
extract($_REQUEST, EXTR_SKIP);
This will not overwrite variables that already exist in your code. See here for other parameters you can use
So I'm new to PHP and am trying to create a form. I accept a bunch of parameters and want to process them in the same page. I'm not sure how to do this without a giant if-else containing the entire page as if($_POST). This doesn't seem ideal.
In addition, I'm finding that I do the following a lot. Is there any way to shorten this? The names all remain the same.
$name = $_REQUEST["name"];
$gender = $_REQUEST["gender"];
$age = $_REQUEST["age"];
And I have a lot of lines which are just doing that, and it seems terribly inefficient
You can use the extract() function to do that. But it has a security downside: existing variables can be overwritten if someone would add variables to the POST header.
Edit: hsz's solution is better
What process you are doing with if..else..if you have to post the code so that we can let you know how that can be shorten.
you can avoid the assignment for each variable using extract function.
extract($_POST);
But be aware that can overwrite your existing variable if the are named same as your input controls.
Stop using $_REQUEST, because it is a combination of $_COOKIE , $_POST and $_GET.
It becomes a security risk.
Instead of using $_REQUEST you should use $_POST here.
$keys = array('name', 'gender', 'age');
foreach ( $keys as $key ) {
if ( isset($_POST[$key]) ) {
$$key = $_POST[$key];
}
// optional:
else {
$$key = ''; // default value
}
}
Magic quotes? http://php.net/manual/en/security.magicquotes.php
For the first thing: Turn it around. Don't do
if ($_POST) {
// Your handling code
} else {
echo "No data!";
}
do
if (!$_POST) {
die("No data!");
}
// Your handling code
You can use extract(), however, this means that you're bringing in a lot of variables that you (might not know about) int your current scope.
My suggestion would be to loop through your array and do something with the variables in there (e.g. - validation)
foreach ($_POST as $key => $valu) {
//do something with the variables
}
Also, don't use $_REQUEST unless you really want to check $_GET, $_POST and $_COOKIE. Use the proper array when accessing variables or people can send data you don't expect.