Need you help in an unusal situation. I need to trim all the $_POST variables.
Is there any way I can do it at a single shot i.e., using a single function?
I know trim($_POST) won't do, I have to make some function like
function sanatize_post(){
foreach ($_POST as $key => $val)
$_POST[$key] = trim($val);
}
But, if you have any other suggestion or comment, please help me.
Thanks
Simply
$_POST = array_map("trim", $_POST);
But if $_POST members (even if 1 of them) is again an array itself, then use recursive version:
function array_map_deep( $value, $callback )
{
if ( is_array( $value ) ) {
foreach ( $value as $index => $item ) {
$value[ $index ] = array_map_deep( $item, $callback );
}
} elseif ( is_object( $value ) ) {
$object_vars = get_object_vars( $value );
foreach ( $object_vars as $property_name => $property_value ) {
$value->$property_name = array_map_deep( $property_value, $callback );
}
} else {
$value = call_user_func( $callback, $value );
}
return $value;
}
Here's a one-liner that will also work either on single values or recursively on arrays:
$_POST = filter_var($_POST, \FILTER_CALLBACK, ['options' => 'trim']);
use array_walk with a custom function
$clean_values = array();
array_walk($_POST, 'sanitize_post');
function sanitize_post($item, $key)
{
$clean_values[$key] = trim($item);
//optional further cleaning ex) htmlentities
}
array_walk($_POST, 'trim') (note that this and the idea might be broken as input name=foo[bar] is translated into an array)
Edit: the above is not correct. Try $_POST = array_map('trim', $_POST);.
You can also use this code I wrote in case you want to sanitize a string OR an array with one function:
function sanitize ($value) {
// sanitize array or string values
if (is_array($value)) {
array_walk_recursive($value, 'sanitize_value');
}
else {
sanitize_value($value);
}
return $value;
}
function sanitize_value (&$value) {
$value = trim(htmlspecialchars($value));
}
Simply use it like this:
$post_sanitized = sanitize($_POST);
$apple_sanitized = sanitize('apple');
Simply use this:
array_walk($_POST, create_function('&$val', '$val = trim($val);'));
and your $_POST is now trimmed.
The other answers did not work well with associative arrays. This recursive functions will trim all values inside a $_POST array all levels down.
// Trim all values of associative array
function trim_associative_array(&$input_array) {
if (is_array($input_array)) {
foreach ($input_array as $key => &$val) {
if (is_array($val)) {
trim_associative_array($val);
} else {
$input_array[$key] = trim($val);
}
}
}
}
I think it's better to use anonymous functions :
array_walk($_POST, function(& $value){
$value = trim($value);
});
Related
Each string value within my $arr array contains 2 preceeding white spaces. I would like to remove these spaces using the trim() method. Furthermore, I would like to do the same for any arrays within the $arr array assuming an infinite number of arrays within arrays. I attempted to do this recursively with no success.
Although there might be a built in php method to do this for me, I am learning, and would like to know why this code block doesn't work as well as what altercation can be made to fix it.
$arr = array(" one", " two", array(" three"));
function trimAll(&$array) {
foreach($array as $key => $value) {
if(gettype($value) !== "array") {
$array[$key] = trim($value);
} else {
trimAll($value);
}
}
}
trimAll($arr);
echo $arr[0];//"one" (worked)
echo $arr[1];//"two" (worked)
echo $arr[2][0];// " three"(didn't work)
The best/simplest function to call in this case is: array_walk_recursive(). There is no need to reinvent a function that php has already designed for just this purpose. It only visits "leaf nodes" so you don't need to check if it is processing an array-type element.
You merely need to modify the elements by reference (using & in the anonymous function parameter). I'll demo ltrim() since your input strings only have leading spaces, but you can use trim() to handle spaces on both sides of the string.
Code: (Demo) (PHP7.4 and higher version)
array_walk_recursive(
$arr,
function(&$v) {
$v = ltrim($v);
}
);
Output:
array (
0 => 'one',
1 => 'two',
2 =>
array (
0 => 'three',
),
)
As for your custom function, it could be written like this to provide a successful result:
function trimAll(&$array) { // modify the original input array by reference
foreach ($array as &$value) { // modify each value by reference
if (!is_array($value)) { // if it is not an array
$value = trim($value); // trim the string
} else {
trimAll($value); // recurse
}
}
}
trimAll($arr); // modify the array (no return value from function call)
var_export($arr); // print the array
You see, the reason your subarray element is not being affected is because there is no assignment occuring between $value and trimAll($value). The way you have set up trimAll, it does not return a value. So, even if you used:
} else {
$array[$key] = trimAll($value);
}
You would find that $array[$key] would be replaced by NULL. The solution is to make $value modifiable by reference by using &$value in the foreach loop.
And as if this answer wasn't long enough already, here is a way to reconfigure your function so that it returns the modified array instead of modifying the input array with no return.
function trimAll($array){ // input array is not modifiable
foreach ($array as &$value) { // $value IS modifiable
if (is_array($value)) { // if an array...
$value = trimAll($value); // assign recursion result to $value
} else { // not an array...
$value = trim($value); // trim the string
}
}
return $array; // return the new trimmed array
}
var_export(trimAll($arr)); // now trimAll() can be directly printed to screen
or if you wish to avoid modifying by reference entirely:
function trimAll($array) {
foreach ($array as $key => $value) {
if (is_array($value)) {
$array[$key] = trimAll($value);
} else {
$array[$key] = trim($value);
}
}
return $array;
}
var_export(trimAll($arr));
Yes, there is a built-in PHP function which solves your problem. It is array_map()
But in your situation, you might need to do something like this:
Solution 1:
$input = array(" one", " two", array(" three"));
function removeSpaces($object)
{
if (is_array($object)) {
$object = array_map('trim', $object);
} else {
$object = trim($object);
}
return $object;
}
$output = array_map('removeSpaces', $input);
Solution 2:
$input = array(" one", " two", array(" three"));
function array_map_recursive(callable $func, array $array) {
return filter_var($array, \FILTER_CALLBACK, ['options' => $func]);
}
$output = array_map_recursive('trim', $input);
Cheers.
Simple method,
$arr = array(" one", " two", array(" three"));
function trimAll(&$array) {
foreach($array as $key => $value) {
if(gettype($value) !== "array") {
$array[$key] = trim($value);
} else {
$array[$key] = trimAll($value);
}
}
return $array;
}
trimAll($arr);
I need to stripslashes all items of an array at once.
Any idea how can I do this?
foreach ($your_array as $key=>$value) {
$your_array[$key] = stripslashes($value);
}
or for many levels array use this :
function stripslashes_deep($value)
{
$value = is_array($value) ?
array_map('stripslashes_deep', $value) :
stripslashes($value);
return $value;
}
$array = array("f\\'oo", "b\\'ar", array("fo\\'o", "b\\'ar"));
$array = stripslashes_deep($array);
print_r($array);
For uni-dimensional arrays, array_map will do:
$a = array_map('stripslashes', $a);
For multi-dimensional arrays you can do something like:
$a = json_decode(stripslashes(json_encode($a)), true);
This last one can be used to fix magic_quotes, see this comment.
You can use array_map:
$output = array_map('stripslashes', $array);
I found this class / function
<?php
/**
* Remove slashes from strings, arrays and objects
*
* #param mixed input data
* #return mixed cleaned input data
*/
function stripslashesFull($input)
{
if (is_array($input)) {
$input = array_map('stripslashesFull', $input);
} elseif (is_object($input)) {
$vars = get_object_vars($input);
foreach ($vars as $k=>$v) {
$input->{$k} = stripslashesFull($v);
}
} else {
$input = stripslashes($input);
}
return $input;
}
?>
on this blog and it really helped me, and now i could pass variables, arrays and objects all through the same function...
Parse array recursevely, with this solution you don't have to dublicate your array
function addslashes_extended(&$arr_r){
if(is_array($arr_r))
{
foreach ($arr_r as &$val){
is_array($val) ? addslashes_extended($val):$val=addslashes($val);
}
unset($val);
}
else
$arr_r=addslashes($arr_r);
return $arr_r;
}
Any recursive function for array :
$result= Recursiver_of_Array($array, 'stripslashes');
code:
function Recursiver_of_Array($array,$function_name=false){
//on first run, we define the desired function name to be executed on values
if ($function_name) { $GLOBALS['current_func_name']= $function_name; } else {$function_name=$GLOBALS['current_func_name'];}
//now, if it's array, then recurse, otherwise execute function
return is_array($array) ? array_map('Recursiver_of_Array', $array) : $function_name($array);
}
I have this kind of simple array:
$puctures=array('1_noname.jpg','2_new.jpg','1_ok.jpg','3_lets.jpg','1_stack.jpg','1_predlog.jpg','3_loli.jpg');
I want to make new array that i will only have elements thats starts with 1_
Example
$new=array('1_noname.jpg','1_ok.jpg','1_stack.jpg','1_predlog.jpg');
Something like array_pop but how?
See array_filter():
$new = array_filter(
$puctures,
function($a) {return substr($a, 0, 2) == '1_'; }
);
A simple loop will do.
foreach ($pictures as $picture) {
if (substr($picture, 0, 2) == "1_") {
$new[] = $picture;
}
}
Use array_filter() to get your array:
$new = array_filter($puctures, function($item)
{
//here strpos() may be a better option:
return preg_match('/^1_/', $item);
});
This examples uses array_push() & strpos()
$FirstPictures = array();
foreach( $pictures as $pic => $value ) {
if ( strpos( $value, '1_' ) !== 0 ) {
array_push( $FirstPictures, $pic );
}
}
$puctures=array('1_noname.jpg','2_new.jpg','1_ok.jpg','3_lets.jpg','1_stack.jpg','1_predlog.jpg','3_loli.jpg');
$new=array();
foreach($puctures as $value)
{
if(strchr($value,'1'))
$new[]=$value;
}
echo "<pre>"; print_r($new);
I want to apply a function to each element/prop of an object but it seems array_walk_recursive() does not work on object. i.e:
if( $re = $con->query("SELECT id, created_date, contents FROM " .
POST_DATA . " WHERE type = 'news' ORDER BY ".
"created_date DESC LIMIT $amount") ) {
if( $re->num_rows != 0 ) {
while( $ob = $re->fetch_object() ) {
$ob = array_walk_recursive( $ob, "_output" );
print_r($ob);
die();
}
}
}
would simply return '1'.
How might I resolve this?
It's actually returning a value of True for array_walk_recursive. If you look at the function's documentation, you'll see that what this method is doing is calling the function _output for each item and key in the object.
You should also have some code that looks similar to this, I would imagine, to get it to work correctly:
function _output($data, $key) {
echo "For the key $key, I got the data: ";
print_r($data);
}
Where _output is called because that is the stringified name that you gave in the array_walk_recursive function. That should print your values to the screen.
Edit:
It seems that I'm not actually answering what you were originally wanting to do, though. If you're wanting to apply a function to every element of an array, I would suggest that you look at array_map. You can use array_map like this:
function double($item) {
return 2 * $item;
}
array_map('double', $item);
Ultimately, if the recursion is something that you desire, you could probably do something like this:
function callback($key, $value) {
// do some stuff
}
function array_map_recursive($callback, $array) {
$new_array = array()
foreach($array as $key => $value) {
if (is_array($value)) {
$new_array[$key] = array_map_recursive($callback, $value);
} else {
$new_array[$key] = call_user_func($callback, $key, $value);
}
}
return $new_array;
}
array_map_recursive('callback', $obj);
That would return another array like $obj, but with whatever the callback was supposed to do.
How can I use array_walk_recursive() instead of this:
function check_value($val){
if(is_array($val)){
foreach($val as $key => $value)
$val[$key] = check_value($value);
return $val;
}
return clean_value($val);
}
?
I think this should do the same thing. Note that argument of a function is passed as a reference (i.e. &$value).
array_walk_recursive($array, function(&$value) {
$value = clean_value($value);
});
For older PHP versions:
function check_value(&$value) {
$value = clean_value($value);
}
array_walk_recursive($array, 'check_value');
I would rewrite the clean_value function to take a reference argument.
For example, these two snippets are functionally identical:
1:
function clean_value($value) {
//manipulate $value
return $value;
}
$value = clean_value($value);
and
2:
function clean_value(&$value) {
//manipulate $value
}
clean_value($value);
For the latter (2), we can use it in array_walk_recursive as follows:
array_walk_recursive($value_tree, 'clean_value');
If we can't edit clean_value, I would solve it as follows:
$clean_by_reference = function(&$val) {
$val = clean_value($val);
};
array_walk_recursive($value_tree, $clean_by_reference);
Hope this helps!
This should work:
function check_value ( $val ) {
if ( is_array ( $val ) ) array_walk_recursive ( $val, 'check_value' );
return clean_value ( $val );
}