Monday 16 July 2018

How to apply a function to every array element in PHP

How to apply a function to every array element in PHP

Here are the various example of how we can apply the function on different inputs along with the output of the variable after the function is applied. In all these examples I will use htmlentities functions as an example function, as it is easy to identify if the function worked or not. htmlentities function converts all applicable characters to HTML entities. In the following examples if the ‘< ‘ and ‘>’ are converted into ‘<‘ and ‘>’ respectively, that means the function got applied correctly.

Apply htmlentites to the value of a variable:

$var = 'some value is <strong>bold</strong>';
$var = htmlentities($var);
var_dump($var);
Output:
string(47) "some value is &lt;strong&gt;bold&lt;/strong&gt;"

Apply htmlentities to single dimensional array:

$array = array();
$array['key1'] = 'value <strong>1</strong>';
$array['key2'] = 'value <strong>2</strong>';
foreach($array as $key => $val)
{
    $array[$key] = htmlentities($val);
}
var_dump($array);
Output:
array(2) {
  ["key1"]=>
  string(36) "value &lt;strong&gt;1&lt;/strong&gt;"
  ["key2"]=>
  string(36) "value &lt;strong&gt;2&lt;/strong&gt;"
}

Apply htmlentities to two-dimensional array.

Method 1: Use array_map function. This method works only if the array is always a two-dimensional array.
$array = array();
$array['key1']['key2'] = 'value <strong>1</strong>';
$array['key1']['key3'] = 'value <strong>2</strong>';
foreach($array as &$val)
{
    $val = array_map('htmlentities', $val);
}
var_dump($array);
Output:
array(1) {
  ["key1"]=>
  &array(2) {
    ["key2"]=>
    string(36) "value &lt;strong&gt;1&lt;/strong&gt;"
    ["key3"]=>
    string(36) "value &lt;strong&gt;2&lt;/strong&gt;"
  }
}
Method 2: There is another way to apply htmlentities to a two-dimensional array without using foreach loop.
$array = array();
$array['key1']['key2'] = 'value <strong>1</strong>';
$array['key1']['key3'] = 'value <strong>2</strong>';
array_walk_recursive($array, function (&$value) {
    $value = htmlentities($value);
});
var_dump($array);
Output:
array(1) {
  ["key1"]=>
  array(2) {
    ["key2"]=>
    string(36) "value &lt;strong&gt;1&lt;/strong&gt;"
    ["key3"]=>
    string(36) "value &lt;strong&gt;2&lt;/strong&gt;"
  }
}

Apply htmlentites to multidimensional array:

In the method 1 to apply the function to a 2-dimensional array, I have used array_map function. However, array_map does not works with multidimensional arrays. Also, array_map does not works recursively hence we need a loop. Let’s see what we will get if we try to use this method on a multidimensional array:
1
2
3
4
5
6
7
8
9
10
11
12
$array = array();
$array['key1']['key11'] = 'value <strong>11</strong>';
$array['key1']['key12'] = 'value <strong>12</strong>';
$array['key2']['key13'] = 'value <strong>13</strong>';
$array['key2'] = 'value <strong>21</strong>';
$array['key3']['key31']['key311'] = 'value <strong>311</strong>';
 
foreach($array as &$val)
{
    $val = array_map('htmlentities', $val);
}
var_dump($array);
Output:
Warning:  array_map() [function.array-map]: Argument #2 should be an array in test.php on line 10
Warning:  htmlentities() expects parameter 1 to be string, array given in test.php on line 10
array(3) {
  ["key1"]=>
  array(2) {
    ["key11"]=>
    string(37) "value &lt;strong&gt;11&lt;/strong&gt;"
    ["key12"]=>
    string(37) "value &lt;strong&gt;12&lt;/strong&gt;"
  }
  ["key2"]=>
  NULL
  ["key3"]=>
  &array(1) {
    ["key31"]=>
    NULL
  }
}
As we saw in the above example, we didn’t get the expected output and also got couple warnings. It didn’t work recursively on all elements of the array. Hence, if you are not sure about the dimensions of the array or if the array has different dimensions at each level then you cannot use array_map. In this case we can use the array_walk_recursive function. The array_walk_recursive function works recursively on the array and hence we don’t need any for loop for it.
$array = array();
$array['key1']['key11'] = 'value <strong>11</strong>';
$array['key1']['key12'] = 'value <strong>12</strong>';
$array['key2']['key13'] = 'value <strong>13</strong>';
$array['key2'] = 'value <strong>21</strong>';
$array['key3']['key31']['key311'] = 'value <strong>311</strong>';
array_walk_recursive($array, function (&$value) {
    $value = htmlentities($value);
});
Output:
array(3) {
  ["key1"]=>
  array(2) {
    ["key11"]=>
    string(37) "value &lt;strong&gt;11&lt;/strong&gt;"
    ["key12"]=>
    string(37) "value &lt;strong&gt;12&lt;/strong&gt;"
  }
  ["key2"]=>
  string(37) "value &lt;strong&gt;21&lt;/strong&gt;"
  ["key3"]=>
  array(1) {
    ["key31"]=>
    array(1) {
      ["key311"]=>
      string(38) "value &lt;strong&gt;311&lt;/strong&gt;"
    }
  }
}
Note: All the examples above work on PHP 5.3+. They won’t work in PHP versions less than PHP 5.3.0, because they do not support anonymous functions. So to make it work with PHP version < 5.3.0 the above code can be modified as follows:
$array = array();
$array['key1']['key11'] = 'value <strong>11</strong>';
$array['key1']['key12'] = 'value <strong>12</strong>';
$array['key2']['key13'] = 'value <strong>13</strong>';
$array['key2'] = 'value <strong>21</strong>';
$array['key3']['key31']['key311'] = 'value <strong>311</strong>';
function my_apply_htmlentities(&$value)
{
    $value = htmlentities($value);
}
array_walk_recursive($array, 'my_apply_htmlentities');
var_dump($array);
Output:
array(3) {
  ["key1"]=>
  array(2) {
    ["key11"]=>
    string(37) "value &lt;strong&gt;11&lt;/strong&gt;"
    ["key12"]=>
    string(37) "value &lt;strong&gt;12&lt;/strong&gt;"
  }
  ["key2"]=>
  string(37) "value &lt;strong&gt;21&lt;/strong&gt;"
  ["key3"]=>
  array(1) {
    ["key31"]=>
    array(1) {
      ["key311"]=>
      string(38) "value &lt;strong&gt;311&lt;/strong&gt;"
    }
  }
}
Note: I have tested all the above codes and all codes (except for the last) work on PHP 5.3.13 and the last one works on PHP 5.2.11

0 comments:

Post a Comment