Sanitizing form data in PHP - php

Is it possible to sanitize all input sent by one method in PHP by simply doing
$var = mysql_real_escape_string($_POST);
and then access elements of $var as I would have of $_POST ?

I don't think you can call mysql_real_escape_string on an array.
But this would work
$cleanData = array_map('mysql_real_escape_string', $_POST);
array_map works by calling the function named in quotes on every element of the array passed to it and returns a new array as the result.
Like superUntitled, I prefer to have a custom function that uses the built-in sanitizing functions as appropriate. But you could still use a custom function with array_map to achieve the same result.

As a side note, I would recommend using a function to sanitize your results:
function escape($txt) {
if (get_magic_quotes_gpc())
$txt = stripslashes($txt);
if (!is_numeric($txt))
$txt = "'" . mysql_real_escape_string($txt) . "'";
return $txt;
}

this function will remove html tags from anything you pass to it
function strip_html(&$a){
if(is_array($a)){
foreach($a as $k=>$v){
$a[$k]=preg_replace('/<[^<]+?>/','',$v);
}
}else{
$a=preg_replace('/<[^<]+?>/','',$a);
}
return;
}

What I find handy is to encapsulate the request data (Post, Get, Cookie etc) in to an Object and then to add a filter method which u can pass an array of function names to. This way you can use it like this:
$array = array('trim','mysql_real_escape_string');
$request->filter($array);
Body of the method works using a loop an array_map like in Mark's example. I wouldn't run the mysql_real_escape_string over my entire $_POST though, only on the necessary fields ( the ones that are getting queried or inserted )

#Shadow:
Array_Map will work with single dimension array but it wont work with multi-dimension arrays.
So, this will work.
$cleanData = array_map('mysql_real_escape_string', $_POST);
but if that $_POST array were to have another array, like this:
$array = $_POST['myArray']['secondArray'];
If you have an array such as above, array map will throw an error when you try to run a function that only takes a String as an argument, because it wont be handle to an array when its expecting just a string.
The solution provided on the below page is much more handy, and does it recursively for every element inside the array.
PHP -Sanitize values of a array

Related

How can I call a function with a dynamic amount of arguments?

I have an array and I need to pass each element of the array as parameters to a function.
Say:
$var = array("var2","var3","var4");
//Pass each element as a new parameter to a function
call_to_function ($var2, $var3, $var4);
//However, if the number of array element change it can be
$var = array("var2","var3");
call_to_function ($var2,$var3);
The problem here is, how to build dynamic number of parameters and call the function.
Use:
PHP Function mysqli_stmt::bind_param, takes multiple parameters. And I need to derive the parameters from an arrray.
Is there any way to do it?
This should work for you:
First you need to create an array with references to the corresponding variables. You can simply do this with a foreach loop like below:
foreach($var as $v) {
$bindValues[] = &$$v;
}
After this you can use call_user_func_array() to call the function to bind the variables. Here it depends if you use procedural or OOP style:
procedural:
call_user_func_array("mysqli_stmt_bind_param", array_merge([$stmt, $types], $bindValues));
OOP:
call_user_func_array([$stmt, "bind_param"], array_merge([$types], $bindValues));
You can use eval() to call the function with dynamic number of parameters.
// Construct the parameter string like "$var[0], $var[1], $var[2]"
$param_str = '';
foreach($var as $key => $val) {
$param_str .= '$var['.$key.'],';
}
$param_str = rtrim($param_str, ',');
eval('call_to_function('.$param_str.');');
Usage of eval() is not considered good practice but if your are sure that your array keys $var are always integer (like in your example default keys) then this should be good to go.
call_user_func_array() is just for that:
call_user_func_array(array($stmt, 'bind_param'), $var);

passing indefinite number of arguments to function without using an array

I am having situation where i want to pass variables in php function.
The number of arguments are indefinite. I have to pass in the function without using the array.
Just like normal approach. Comma Separated.
like test(argum1,argum2,argum3.....,..,,.,.,.....);
How i will call the function? Suppose i have an array array(1,2,3,4,5) containing 5 parameters. i want to call the function like func(1,2,3,4,5) . But the question is that, How i will run the loop of arguments , When calling the function. I tried func(implode(',',array)); But it is taking all return string as a one parameters
In the definition, I also want the same format.
I can pass variable number of arguments via array but i have to pass comma separated.
I have to pass comma separated. But at the time of passing i don't know the number of arguments , They are in array.
At the calling side, use call_user_func_array.
Inside the function, use func_get_args.
Since this way you're just turning an array into arguments into an array, I doubt the wisdom of this though. Either function is fine if you have an unknown number of parameters either when calling or receiving. If it's dynamic on both ends, why not just pass the array directly?!
you can use :
$function_args = func_get_args();
inside your test() function definition .
You can just define your function as
function test ()
then use the func_get_args function in php.
Then you can deal with the arguments as an array.
Example
function reverseConcat(){
return implode (" ", array_reverse(func_get_args()));
}
echo reverseConcat("World", "Hello"); // echos Hello World
If you truely want to deal with them as though they where named parameters you could do something like this.
function getDistance(){
$params = array("x1", "y1", "x2", "y2");
$args = func_get_args();
// trim excess params
if (count($args) > count($params) {
$args = array_slice(0, count($params));
} elseif (count($args) < count($params)){
// define missing parameters as empty string
$args = array_pad($args, count($params), "");
}
extract (array_combine($params, $args));
return sqrt(pow(abs($x1-$x2),2) + pow(abs($y1-$y2),2));
}
use this function:
function test() {
$args = func_get_args();
foreach ($args as $arg) {
echo "Arg: $arg\n";
}
}
I'm not sure what you mean by "same format." Do you mean same type, like they all have to be a string? Or do you mean they need to all have to meet some criteria, like if it's a list of phone numbers they need to be (ddd) ddd-dddd?
If it's the latter, you'll have just as much trouble with pre-defined arguments, so I'll assume you mean you want them all to be the same type.
So, going off of the already suggested solution of using func_get_args(), I would also apply array_filter() to ensure the type:
function set_names() {
function string_only($arg) {
return(is_string($arg));
}
$names_provided = func_get_args();
// Now you have an array of the args provided
$names_provided_clean = array_filter($names_provided, "string_only");
// This pulls out any non-string args
$names = array_values($names_provided_clean);
// Because array_filter doesn't reindex, this will reset numbering for array.
foreach($names as $name) {
echo $name;
echo PHP_EOL;
}
}
set_names("Joe", "Bill", 45, array(1,2,3), "Jane");
Notice that I don't do any deeper sanity-checks, so there could be issues if no values are passed in, etc.
You can use array also using explode http://www.php.net/manual/en/function.explode.php.
$separator = ",";
$prepareArray = explode ( $separator , '$argum1,$argum2,$argum3');
but be careful, $argum1,$argum2, etc should not contain , in value. You can overcome this by adding any separator. $separator = "VeryUniqueSeparator";
I don't have code so can't tell exact code. But manipulating this will work as your requirements.

PHP get array() value to become $variable

ok, So I have this array:
$choices = array($_POST['choices']);
and this outputs, when using var_dump():
array(1) { [0]=> string(5) "apple,pear,banana" }
What I need is the value of those to become variables as well as adding in value as the string.
so, I need the output to be:
$apple = "apple";
$pear = "pear";
$banana = "banana";
The value of the array could change so the variables have to be created depending on what is in that array.
I would appreciate all help. Cheers
Mark
How about
$choices = explode(',', $_POST['choices']);
foreach ($choices as $choice){
$$choice = $choice;
}
$str = "apple,pear,pineapple";
$strArr = explode(',' , $str);
foreach ($strArr as $val) {
$$val = $val;
}
var_dump($apple);
This would satisfy your requirement. However, here comes the problem, since you could not predefine how many variables are there and what are they, it's hard for you to use them correctly. Test "isset($VAR)" before using $VAR seems to be the only safe way.
You'd better just split the source string in just one array and just operate the elements of the specific array.
I have to concur with all the other answers that this is a very bad idea, but each of the existing answers uses a somewhat roundabout method to achieve it.
PHP provides a function, extract, to extract variables from an array into the current scope. You can use that in this case like so (using explode and array_combine to turn your input into an associative array first):
$choices = $_POST['choices'] ?: ""; // The ?: "" makes this safe even if there's no input
$choiceArr = explode(',', $choices); // Break the string down to a simple array
$choiceAssoc = array_combine($choiceArr, $choiceArr); // Then convert that to an associative array, with the keys being the same as the values
extract($choiceAssoc, EXTR_SKIP); // Extract the variables to the current scope - using EXTR_SKIP tells the function *not* to overwrite any variables that already exist, as a security measure
echo $banana; // You now have direct access to those variables
For more information on why this is a bad approach to take, see the discussion on the now deprecated register_globals setting. In short though, it makes it much, much easier to write insecure code.
Often called "split" in other langauges, in PHP, you'd want to use explode.
EDIT: ACTUALLY, what you want to do sounds... dangerous. It's possible (and was an old "feature" of PHP) but it's strongly discourage. I'd suggest just exploding them and making their values the keys of an associative array instead:
$choices_assoc = explode(',', $_POST['choices']);
foreach ($choices as $choice) {
$choices_assoc[$choice] = $choice;
}

Will this allow for mysql_real_escape_string to work globally?

$_POST = mysql_real_escape_string($_POST);
By executing this statement, does each post value now get escaped via mysql_real_escape_string?
No. That won't work at all: $_POST is an array: mysql_real_escape_string needs a string as its first argument. You can, however, achieve what you want with array_map:
$_POST = array_map('mysql_real_escape_string', $_POST);
Or array_walk_recursive as array_map does not work on array post values:
array_walk_recursive($_POST, function(&$v, $k) {$v = mysql_real_escape_string($v);});
Better, however, would be to use paramaterised queries: this is by far the most secure way to avoid SQL injection. Not only does the above option do needless escaping (for instance, members of the $_POST array that don't need to be inserted into the database), it also makes it harder to use the data in other contexts, e.g. returning them to the browser in some way.
No, but you can use array_walk()Docs or array_walk_recursive()Docs to achieve that, as mysql_real_escape_string()Docs requires a string (go figure...) as input, and you're passing it an array instead.
With this, you pass each array element the same callback function:
array_walk_recursive($_POST, 'escape');
escape($k,$v)
{
return mysql_real_escape_string($v);
}
But it's better to treat each value accordingly, for ex. casting an INT to INT, etc., or better yet, use parametrized queries.
Since $_POST is an array, this will going to give you an error.
link: http://php.net/manual/en/function.mysql-real-escape-string.php
$escapedPost = array_map(array($this, 'recursive_escape'), $_POST);
/**
* recursively escape an array containing strings and/or arrays
*/
function recursive_escape($value) {
if (is_array($value)) {
array_map(array($this, 'recursive_escape'), $value);
} else {
$value = mysql_real_escape_string($value);
}
return $value;
}

how to delete item from an array with filter?

I want to filter and delete an item from an array. is it possible to do it with array_filter() ?
//I want to delete these items from the $arr_codes
$id = 1223;
$pin = 35;
//Before
$arr_codes = Array('1598_9','1223_35','1245_3','1227_11', '1223_56');
//After
$arr_codes = Array('1598_9','1245_3','1227_11', '1223_56');
Thanks!
You can find the index of the value you are interested in with array_search and then unset it.
$i = array_search('1223_35',$arr_codes);
if($i !== false) unset($arr_codes[$i]);
array_filter does not take userdata (parameters). array_walk() does. However, none of the iterator function allow modifying the array structure within the callback.
As such, array_filter() is the appropriate function to use. However, since your comparison data is dynamic (per your comment), you're going to need another way to obtain comparison data. This could be a function, global variable, or build a quick class and set a property.
Here is an example using a function.
array_filter($arr, "my_callback");
function my_callback($val) {
return !in_array($val, get_dynamic_codes());
}
function get_dynamic_codes() {
// returns an array of bad codes, i.e. array('1223_35', '1234_56', ...)
}

Categories