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.
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
So here I am again trying to find better ways of doing things. 90% of tutorials do things the normal way below:
if (isset($_POST['name']) && isset($_POST['password'])) {
// Does some stuff...
}
It is fine but it does seem too static since I prefer something far more dynamic. For example lets say looping through all $_POST arrays within a contact form. This way I can change the name or the fields to whatever I want or add more...my code will always handle the rest.
I know a foreach loop would come in handy but, as someone new to the world of programming and php I thought you could show me how something like this is done. So how do I replace the above with a for loop? I am not sure where to start.
try this:
$check=true;
if(isset($_POST)){
foreach($_POST as $key=>$value){
if(!isset($_POST[$key]){
$check = false;
break;
}
}
}
based on $check you can verify if it was properly sent or not.
Another approach is to have a sort of verification because it is possible you might not get the key in $_POST
$keys =array("input1","input2");
$check=true;
if(isset($_POST)){
foreach($keys as $input){
if(!array_key_exists($input,$_POST)){
$check = false;
break;
}
}
}
Well you could try something like this :-
<?php
$inputNames = array("input1","input2");
foreach($inputNames as $input)
{
if (isset($_POST["$input"]) && isset($_POST["$input"])) {
// Does some stuff...
}
}
?>
Make an array with the names of all your input tags, and then simply do a foreach between them. In this way, you always only need to edit the names array.
You can always use foreach loop like that:
foreach($_POST as $key => $value){ echo '$_POST["'.$key.'"] = "'.$value.'"'}
But remember, that anyone, can modify your form, prepare some post statement and send data that can create little mess with your code. So it`s good way to validate all fields.
Dynamic validation is of course possible, but you need to do it right!
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.
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
I am getting tried of if isset($_GET['whatever'])... before the rest of my if statement. E_NOTICE errors are way to handy to turn off and for $_POST variables I have a solution in my init script..
$POST = (is_array( $_POST ) && count( $_POST ) > 0);
I find this helps self posting scripts look clean.
if ($POST) {
// now do something with $_POST...
}
I'm not sure how to dynamically do this if you have no idea what the key is? Can anyone help find a similar solution for $_GET variables?
EDIT:
I simply want if ($_GET['whatever'] == "whatever"); to return false if it's not set and no E_NOTICE errors.
EDIT:
Sorry if I'm unclear I'm looking for a solution for $_GET not $_POST--I only am using $_POST as an example of what I hope to achieve.
Sometimes I use a global GET function:
function GET($key, $default = null) {
return isset($_GET[$key]) ? $_GET[$key] : $default;
}
The main idea of all that mess is simple: every variable in your program should be initialized before use.
Thus, the best you can do is to set all variables centralized, say, at the very top of your script.
But there are some different cases. For the case you posted, you need none of these but
if ($_SERVER['REQUEST_METHOD'] == "POST")
Already answered, but since it wasn't mentioned, also try:
$var = filter_input(INPUT_GET, 'varname');
That will return null if it doesn't exist, without the annoying array notices, and also filters out potential bad stuff in various ways. See also: http://www.php.net/filter
You can make a function to do this for you.
function getVar($item){
return isset($_GET[$item]) ? $_GET[$item] : '';
}
Then you can do if(getVar('whatever') == "whatever").
Here are two methods.
/*
* Makes any request keys into variables of the same name
*/
foreach($_GET AS $key => $value) {
${$key} = ($value);
}
//Assuming a input key of $_GET['whatever']
echo $whatever;
/*
* Casting to an object
*/
$get = (object) $_GET;
//Assuming a input key of $_GET['whatever']
echo $get->whatever
A third option that I can think of is making the $_GET into its own class. PHP overloading is handy trick for doing this.
http://php.net/manual/en/language.oop5.overloading.php
I didn't feel like writing up an example demonstrating this. :)
simple I think you want to check if get value is set then need to do the next step otherwise do different
I like the first answer but need to check thats if it works for you
if(isset($_GET['whatever']){
if ($_GET['whatever'] == "whatever");{
//do the rest
}
else{
//do the rest
}
}
hope it may help if what I think is your need
short
no notice
$key = &$_POST['key'];
This way (inside function) it is depracted, and shows error:
function f($s){}
f(&$_POST['key']);
Fatal error: Call-time pass-by-reference has been removed
When writing these sorts of scripts, I usually do something like this at the top:
$submitted = isset($_POST['submit']) ? true : false;
$username = isset($_POST['username']) ? $_POST['username'] : null;
$password = isset($_POST['password']) ? $_POST['password'] : null;
(etc.)
Then, when testing the values, it looks something like this:
if ($submitted)
{
if ($username && $password)
{
// do stuff with username and password including testing their values
}
}
It seems to work pretty well for me.