Post variable array question

Is it possible to take all the posted variables from a script and instead of (empty($_POST[‘save’])) everyone
do something like, any direction would be great thanks


function myPostVariable (){
             while ($postvariables)             
             
             //check to see if its empty

            //place into my array 

}

instead of :


$sa = (empty($_POST['sa'])) ? "" : $_POST['sa'] ;
$cG= (empty($_POST['cg])) ? "" : $_POST['cg] ;
$cS= (empty($_POST['cs]))? "" : $_POST['cs'] ;
$rS= (empty($_POST['rs]))? "" : $_POST['rs'] ;
$rM= (empty($_POST['rm']))? "" : $_POST['rm'] ;
$rI= (empty($_POST['ri']))? "" : $_POST['ri'] ;




$userCurrentSave = array(
"cG" => "$sa",
"cS" => "$cG",
"rS" => "$cS",
"rM" => "$rM",
"rI" => "$rI",

);


Use foreach() to iterate through POST.

To expand on Sam32’s point, you could do something like this:


$userCurrentSave = array();
foreach ($_POST as $key => $value) {
    $userCurrentSave[$key] = empty($value) ? '' : $value;
}

But…

If this is POST information that you’ve gotten from a form being submitted, then all the “empty” values are going to be empty strings anyway, right? Transferring the POST data straight to another array without doing anything to it seems like a waste of time.

This may seem like a lot of repeated code but it has one huge advantage: readability. In this example you look at the code and immediately you know where each variable comes from, because you can see one by one which variables you are grabbing from $_POST data. That’s why they are removing register_globals from php, because it allowed to skip this code above and all POST, GET and COOKIE variables automatically appeared as variables. Then it became a real pain to look at the code and have no idea where a variable is coming from - a bloody mess! Sure, you could copy them to another array like $my_post but it wouldn’t make a lot of sense.

BTW, be careful about empty() because it will treat the value of “0” as empty - sometimes “0” is a valid value you want to accept, then use isset() instead.

I fiddled with array_map and crashed but this seems to work:


// spoofiing your inputs for now...
$_POST['var1'] = "";
$_POST['var2'] = "0";
$_POST['var3'] = "thing3";
$_POST['var4'] = "thing4";
$_POST['var5'] = "1";

$_POST = array_filter($_POST);

var_dump( $_POST );

// gives
//array
//  'var3' => string 'thing3' (length=6)
//  'var4' => string 'thing4' (length=6)
//  'var5' => string '1' (length=1)

Full disclosure: Googled and found this thoughtful and clever chap http://briancray.com/2009/04/25/remove-null-values-php-arrays/ who nicely credited another clever chap called Paul Scott, that’s the PHP spirit!

Er… Does it?
Check var2 there, Cups… “0” could be valid input.

Empty may not be what you’re after, purencool.

So could it be done with array_map() I wonder?

There must be a better way to apply a filter to a multi array than reallocating the vars as in LemonJuices solution in #4.


<?php
$array = array(
	'a'	=> '',
	'b'	=> null,
	'c'	=> '1',
	'd'	=> '0',
	'e'	=> 'false',
	'f'	=> 'true',
);


var_dump(
	array_filter($array, 'strlen')
);


/*
	array(4) {
		["c"] => string(1) "1"
		["d"] => string(1) "0"
		["e"] => string(5) "false"
		["f"] => string(4) "true"
	}
*/

:slight_smile:

Anthony.

Nice one Anthony, forgot the callback option.

Having said that the OP might be interested in [fphp]filter_input_array[/fphp] too.

These are all nice examples of filtering arrays but still I don’t see the point of filtering $_POST just to remove empty values. What purpose does it serve? This would only make the code harder to debug because somewhere further down your code you check, e.g. for $_POST[‘id’] and find out it is not set. And you wonder, what’s going on, $_POST[‘id’] should have been sent by a form on a previous page but it doesn’t look like this actually happened. So you check whether your form is okay - and well, you are on the wrong track because the form is fine only $_POST[‘id’] has been unset magically by a filter function. In my opinion this kind of filtering is just a waste of (programmer’s) time and adds confusion.

Also, often each $_POST variable needs to be treated separately - on some I can happily use empty() as the best check (0/1 booleans, db id’s, etc.) while on others isset() is more appropriate, while still others can be arrays and I need to use a completely different kind of check. A universal filter will never be able to cope with all of that well.

So far I think the best solution is still the ‘clumsy’ code the OP posted:

$sa = (empty($_POST['sa'])) ? "" : $_POST['sa'] ;
$cG= (empty($_POST['cg])) ? "" : $_POST['cg] ;
$cS= (empty($_POST['cs]))? "" : $_POST['cs'] ;
$rS= (empty($_POST['rs]))? "" : $_POST['rs'] ;
$rM= (empty($_POST['rm']))? "" : $_POST['rm'] ;
$rI= (empty($_POST['ri']))? "" : $_POST['ri'] ;

  • provided that he uses all those variables immediately after assigning them so that later on he doesn’t have to hunt through the code to find where $cG comes from - he can see it a few lines above.

I sincerely follow your point, and to some degree do agree with you.

We often get caught up in programming pi$$ing contents just for the fun of it, and I’m as guilty as the next man.

However the point about readability was one I was actually trying to address in a search for an array_map solution, in that I could have then wrapped that in a clearly labelled function.


removeZerosAndEmptyStrings($_POST);

Which could itself have evolved from a family of similar functions, or maybe a class…

Whether that would have resulted in easier to understand code, I am not sure - I’d have to see that line in code then I’d know whether I was barking up the wrong tree or not.

But to tbh, to see lines of repetitive code – that could in principle go on forever – would cause me severe sleep loss.

Looking at the OP code again:


$sa = (empty($_POST['sa'])) ? "" : $_POST['sa'] ;
// ... ad nauseum

$userCurrentSave = array(
"cG" => "$sa",
// ... ad nauseum

I think the OP should really ask themselves why does a POST key name ‘sa’, get reallocated to $sa and then get reallocated to the array key ‘cG’?

From the name of the variable it looks as if this is then being passed direct to the database.

If ‘cG’ is say, a field in the database then the form element should have the name=“cG” - then you can think about unsetting all the empties (and pass the whole array to ‘mysql_real_escape_string’ maybe?) then just past POST to $userCurrentSave;

I don’t think replacing all of that code with something like this is obfuscating the intent at all:


$userCurrentSave = removeZerosAndEntpyStrings($_POST);

And unless we get signs telling us otherwise - we don’t really care what is going on inside removeZerosAndEntpyStrings(), or how ugly that code is as long as it is dependable and does what it says on the tin.

I think sometimes there is no escaping from repeating ‘ad nauseum’ in a secure code… Suppose we are writing POST data (many fields) into a db table, we have to somehow specify a list of fields we are accepting from the form. If we don’t then how will our application know which fields should be put into an INSERT/UPDATE query? If we just accept any form field as data to be written to db then it’s a security whole because someone may inject a field that isn’t supposed to be changed by a user. The enumeration doesn’t have to be done like the OP shows us but I think it has to be done somehow, e.g. like this:


// this will grab only enumerated field names from $_POST
$data = array_intersect_key($_POST, array_flip('sa', 'cG', 'cS', 'rS', 'rM', 'rI'));

// now I can safely put all $data into db using some convenience function...
$db->insert('table', $data);

Actually, I sometimes use code similar to the above to lessen the amount of lines I’d have to repeat ‘ad nauseum’ for each field.

But still in such cases it makes no sense to filter (unset) fields which are zeroes or empty strings. If a field is an empty string it means it has to be written as empty string (or NULL) to db and I need it to be present in my set of data. After removeZerosAndEmptyStrings($_POST) such fields don’t exist at all which means they aren’t written or updated at all - the meaning is completely different. Of course, it all depends on the specific problem you are dealing with and the underlying frameworks you use - but I’ve never yet had a need for removeZerosAndEmptyStrings($_POST) function. All values are meaningful, even zeroes and empty strings, and fitering them out is like removing their corresponding fields from the web form.

I think the OP should really ask themselves why does a POST key name ‘sa’, get reallocated to $sa and then get reallocated to the array key ‘cG’?

From the name of the variable it looks as if this is then being passed direct to the database.

I agree, perhaps too many reallocations here. But if he is using these variables more than once then it’s convenient to have a shortcut like $cG rather than having to type the conditions every time.

Sometimes I think in such cases error suppression can be handy, I know it shouldn’t be used but just see how much simpler it looks then:


$userCurrentSave = array(
  "cG" => @$_POST["cG"],
  "cS" => @$_POST["cS"],
  "rS" => @$_POST["rS"],
  "rM" => @$_POST["rM"],
  "rI" => @$_POST["rI"],
);

In this case if a value doesn’t exist it is converted to null and we don’t have to use conditionals to avoid notice errors. To me this is one of the few acceptable usages of @.

Maybe it all depends on programmer’s habits. Some years ago I created my own functions that dealt with a bulk of POST data by performing some trimming, filtering, etc. but then when I was revisiting my code after a long time it wasn’t always clear to me how the data was transformed or filtered without having to scan more code. So now I prefer to repeat plain $_POST even with a conditional empty() or isset() so that the code is 100% obvious when I look at it.

The solution we choose will depend on the problem in hand.

If dealing with say, a general contact form containing 10 fields all containing different types of values, postcode, email address, tel nos and so on then yes - seeing them listed in order, seeing the appropriate filtering being applied makes perfect sense - for which your solution is totally logical and good practice.

If your form data is coming from a logged in user and contains 100 integer widget selections then semi-automating the checking and insertion of those data into storage also makes perfect sense.

For those cases in between, well, it will depend.

I have never needed to create or use a removeZerosAndEmptyStrings() function myself, so cannot advocate its use.

I chose that name in order to focus the OPs mind upon how function naming can indeed play an import part in clarifying what a piece of code does in the context of the conversations and code preceding it and the original question.

Sorry for repeating myself everyone, but this might be a good read for the OP, or anyone else wondering if/how they can start to get away from writing code whose contents seem to vary little: Loops are good

thanks for all your help I have enjoyed the discussion the podcast is right there is a great community at sitepoint