views:

479

answers:

6

How do I run the PHP function htmlspecialchars() on an array of array objects?

I have the following code:

$result_set = Array
(
    [0] => Array
        (
            [home_id] => 1
            [address] => 4225 Nasmyth Dr
            [city] => Plano
            [state] => TX
            [zip] => 76798
        )

    [1] => Array
        (
            [home_id] => 8
            [address] => 4229 Nasmyth Dr
            [city] => Plano
            [state] => TX
            [zip] => 75093
        )
);

// this doesn't work since $result_set is an array of arrays and htmlspecialchars is expecting a string
htmlspecialchars($result_set, ENT_QUOTES, 'UTF-8')); 

UPDATE:

Please note that even though there are quite a few answers below, none of them work for an array-of-arrays. The answers below only work for simple arrays.

I've tried the following, but it doesn't work:

array_walk_recursive($result_set, "htmlspecialchars", array(ENT_QUOTES,'UTF-8'))

I get the following error: htmlspecialchars() expects parameter 2 to be long, string given


UPDATE 2

When I try:

function cleanOutput(&$value) {
    return htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
}
print_r($result_set);
print('-------');
print_r(array_walk_recursive($result_set, "cleanOutput"));

I get the following, undesired, output:

Array
(
    [0] => Array
        (
            [home_id] => 1
            [address] => 4225 Nasmyth Dr
            [city] => Plano
            [state] => TX
            [zip] => 76798
        )
    [1] => Array
        (
            [home_id] => 8
            [address] => 4229 Nasmyth Dr
            [city] => Plano
            [state] => TX
            [zip] => 75093
        )
)
-------1

UPDATE 3

When I try:

function cleanOutput(&$value) {
    return htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
}
$result_set = Array
    (
        [0] => Array
            (
                [home_id] => 1
                [address] => 4225 Nasmyth Dr
                [city] => Plano
                [state] => TX
                [zip] => 76798
            )

        [1] => Array
            (
                [home_id] => 8
                [address] => 4229 Nasmyth Dr
                [city] => Plano
                [state] => TX
                [zip] => 75093
            )
    );

$cleanedOutput = array();
foreach ($result_set as $rs) {
    $cleaned[] = array_map("cleanOutput", $rs);
}
print_r($cleanedOutput);

I get the following, undesired, results:

{'homes' : []}
+11  A: 

You can use array_map() to run that method on each entry.

$cleaned = array_map("htmlspecialchars", $myArray);

If you need to pass arguments to htmlspecialchars(), you can substitute it for your own custom function:

function myFunc($a) {
  return htmlspecialchars($a, ENT_QUOES);
}

$cleaned = array_map("myFunc", $myArray);

Considering the fact that you're dealing with an array of arrays, and not an array of strings, you would need to cycle through the outer-array to get to your strings:

$cleaned = array();
foreach ($result_set as $rs) {
  foreach ($rs as $r) {
    $cleaned[] = array_map("htmlspecialchars", $r);
  }
}

Or, you could use array_walk_recursive():

array_walk_recursive($myArray, "htmlspecialchars");

Note that this method changes the $myArray object by reference, so there's no need to assign the output to a new variable.

Jonathan Sampson
very cool!!!!!!
antpaw
How do I use array_map() if I want to pass agruments to htmlspecialchars? Meaning, how do I pass the arguements of ENT_QUOTES, 'UTF-8'" to htmlspecialchars?
TeddyR
Meaning, 'array_map("htmlspecialchars", $result_set)' does not allows me to pass in the argument of ENT_QUOTES and UTF-8
TeddyR
TeddyR, make your own function that calls htmlspecialchars with those arguments, and call your function instead.
Jonathan Sampson
Why wouldn't this work --> array_map('htmlspecialchars', $result_set, array(ENT_QUOTES, 'UTF-8')) ???
TeddyR
I receive the following error, "htmlspecialchars() expects parameter 2 to be long, string given" when using rray_map('htmlspecialchars', $result_set, array(ENT_QUOTES, 'UTF-8'))
TeddyR
@tvanover, so how do I advert this error?
TeddyR
@Jonathan Sampson, why do I need to create another function (myFunc)?
TeddyR
The arrays passed to array_map should be of equal length. The argument list for the callback function is comprised of one element from each array. If you wanted to do it this way, the call to array_map would look like this: array_map('htmlspecialchars', $result_set, array_fill(0, count($result_set), ENT_QUOTES), array_fill(0, count($result_set), 'UTF-8')). Take Jonathan's advice. It's much simpler and cleaner.
bish
You could also use an anonymous function (PHP 5.3 and later) that calls `htmlspecialchars` with the appropriate arguments:http://php.net/manual/en/functions.anonymous.php
Will Vousden
@bish, I receive an error when trying your way. The error is: "array_fill() [<a href='function.array-fill'>function.array-fill</a>]: Number of elements must be positive in"
TeddyR
@TeddyR Make sure count($result_set) is actually returning the length of the $result_set array. If it's returning 0, that will cause the error you're seeing.
bish
@Jonathan, when I try your way - I receive the following error: "htmlspecialchars() expects parameter 1 to be string"
TeddyR
@TeddyR, your first-level types are arrays. $result_set[0] is an array, not a string. Within your clean-method you need to address the strings, not arrays.
Jonathan Sampson
@Jonathan, so how would I do this then given that I have an array of arrays
TeddyR
@TeddyR, you could use `foreach`.
Jonathan Sampson
See my updated solution.
Jonathan Sampson
@Jonathan, thanks for the update ... just one last question. What's the most efficient way if I also wanted to pass the ENT_QUOTES and 'UTF-8' agruments to the htmlspecialchars() function using an array-of-arrays?
TeddyR
when I try: array_walk_recursive("htmlspecialchars", $result_set, array(ENT_QUOTES,'UTF-8')) .... I get the following error: "Only variables can be passed by reference"
TeddyR
Your array is the first argument in `array_walk_recursive`, not the second.
Jonathan Sampson
When I update my code to: array_walk_recursive($result_set, "htmlspecialchars", array(ENT_QUOTES,'UTF-8')) ... , I get a new error: "htmlspecialchars() expects parameter 2 to be long, string"
TeddyR
@Jonathan, any ideas? You've been of huge help so far.
TeddyR
@TeddyR, if you wish to use additional arguments, it appears you should go with my earlier suggestion, `foreach` and `array_map` according to the consensus on this page: http://stackoverflow.com/questions/1317063/php-htmlspecialchars-error
Jonathan Sampson
@Jonathan, using the foreach doesn't work. See my UPDATE 3 to my original post.
TeddyR
@TeddyR, oh, I think you'll need a nested-foreach. See my updated foreach.
Jonathan Sampson
+3  A: 

You may wish to use array_map as Jonathon Sampson suggested, another alternative is array_walk

The difference is that array_map returns a copy of the array with the function applied to each element, while array_walk operates directly on the array you supply.

Alex JL
A: 

If you want to use array_map and pass the function arguments, you can create your own function and use that as the callback:

 function cleanhtml($dirtyhtml) {
       return htmlspecialchars($dirtyhtml, UTF-8);
  }

  $cleaned = array_map("cleanhtml", $myArray);
Anthony
you don't really need your own function, array_map can pass multiple arguments to the target callback function. array array_map ( callback $callback , array $arr1 [, array $... ] ) The only time you would want to create your own is if you are doing more than one thing to every object in the array.
tvanover
I noticed that from the comment above. But the php documentation does NOT make it very clear. One simple example would really be helpful. All of their examples assume user-written functions.
Anthony
This generates the following error: "htmlspecialchars() expects parameter 1 to be string" when I use the following code: function cleanhtml($dirtyhtml) { return htmlspecialchars($dirtyhtml, ENT_QUOTES,'UTF-8'); } $cleaned = array_map("cleanhtml", $myArray);
TeddyR
A: 

You don't need to create your own function if you are passing multiple arguments to the called back function.

According to php.net:

array array_map ( callback $callback , array $arr1 [, array $... ] )

So that means if you want to pass multiple arguments you should just pass:

$clean_array = array_map("htmlspecialchars", $myArray, array(ENT_QUOTES, 'UTF-8'));

but for some reason this doesn't work for me.

But this seems to does, don't ask me why.

$clean_array = array_map("htmlspecialchars", $myArray, array(ENT_QUOTES), array('UTF-8'));
tvanover
This does not work. I receive the error: array_map() [<a href='function.array-map'>function.array-map</a>]: Argument #3 should be an array
TeddyR
So, I'm stumped. Because neither your way nor Jonathan's way works. Both generate errors, see my comments for the exact errors.
TeddyR
I have revised it, it seems to work for me, but test it and see if it outputs properly for you. For some reason if I put both arguments in the same array it stated that "htmlspecialchars() expects parameter 2 to be long". You got me.
tvanover
@travover, In your second example, I receive the following error: "htmlspecialchars() expects parameter 1 to be string, array given"
TeddyR
@tvanover This would only work for the first element of the array. Look at Example #3 in the documentation and the comment immediately after it as to why.
bish
Well nuts, Looks like the custom function is the one. Or do the array_fill.
tvanover
A: 
function filter(&$value) {
  $value = htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
}
array_walk_recursive($result_set, "filter");
print_r($result_set);
JW
Shouldn't this work ---> array_walk_recursive("htmlspecialchars", $result_set, array(ENT_QUOTES,'UTF-8')) ... but it doesn't. I get the error: "Only variables can be passed by reference"
TeddyR
Looks like I have the ordering wrong on my parameters. It should be: array_walk_recursive("htmlspecialchars", $result_set, array(ENT_QUOTES,'UTF-8')) ... but now I get a new error: "htmlspecialchars() expects parameter 2 to be long, string given"
TeddyR
JW
@JW, I've tried the following, but it doesn't work:array_walk_recursive($result_set, "htmlspecialchars", array(ENT_QUOTES,'UTF-8'))I get the following error: htmlspecialchars() expects parameter 2 to be long, string given
TeddyR
@JW, any ideas?
TeddyR
Try the code as I wrote it first. You're misunderstanding the way the third argument to array_walk_recursive works. Check the manual page here: http://php.net/manual/en/function.array-walk-recursive.php
JW
@JW, when I try your code above - it returns an empty array. Even when I change you code from: $value = htmlspecialchars($value, ENT_QUOTES, 'UTF-8'); to return htmlspecialchars($value, ENT_QUOTES, 'UTF-8'); ... it still doesn't work
TeddyR
It's not returning anything -- it's modifying $result_set in-place. Do print_r($result_set) after you run my code, and you'll see the results.
JW
@JW, see UPDATE 2 for the full results in the original post.
TeddyR
@JW, as you can see in UPDATE 2 - strange why it isn't working. You can see the output in the original post.
TeddyR
In UPDATE 2, you're still printing the return value of array_walk_recursive, which is not what you want. Just print $result_set. Slow down a second and read the manual page for array_walk_recursive ... you'll see how it works. I modified my example above to print the array.
JW