2

I'm trying to build a function that will apply html_entity_decode to objects and arrays. Since I don't know the structure beforehand, and the child properties can also be objects or arrays, a simple recursive function seemed to be the way to go. I'm unable to figure out why the following does not work:

function decode($data){  
    if(is_object($data) || is_array($data)){
        foreach($data as &$value)
            $value = $this->decode($value);
    }
    else $data = html_entity_decode($data);

    return $data;
}

I have also tried the following, which doesn't work either:

function decode($data){
    if(is_object($data))
        $data = get_object_vars($data);

    $data = is_array($data) ? array_map(array('MyClassName', 'decode'), $data) : html_entity_decode($data);

    return $data;
}

Neither function has any affect on the data. What am I doing wrong?

0

3 Answers 3

10
+100

The main issue is that you are trying to work with object like array is_object($data) || is_array($data) would not really work except you convert the object to array

Other Issues are base on incorrect variable name and not returning the proper variable You can try

$std = new stdClass();
$std->title = array("x" => "<a>XXX</a>","y" => "<b>YYY</b>");
$std->body = "<p> THis is the Body </p>";

$var = array(
        "a" => "I'll \"walk\" the <b>dog</b> now",
        "b" => array("<b>Hello World</b>",array(array("Yes am <strong> baba </strong>"))),
        "c" => $std

);

$class = new MyClassName();
$encode = $class->encode($var); // encode 
$decode = $class->decode($encode);  // decode it back

print_r($encode);
print_r($decode);

Encoded Array

Array
(
    [a] => I'll &quot;walk&quot; the &lt;b&gt;dog&lt;/b&gt; now
    [b] => Array
        (
            [0] => &lt;b&gt;Hello World&lt;/b&gt;
            [1] => Array
                (
                    [0] => Array
                        (
                            [0] => Yes am &lt;strong&gt; baba &lt;/strong&gt;
                        )

                )

        )

    [c] => stdClass Object
        (
            [title] => Array
                (
                    [x] => &lt;a&gt;XXX&lt;/a&gt;
                    [y] => &lt;b&gt;YYY&lt;/b&gt;
                )

            [body] => &lt;p&gt; THis is the Body &lt;/p&gt;
        )

)

Decoded Array

Array
(
    [a] => I'll "walk" the <b>dog</b> now
    [b] => Array
        (
            [0] => <b>Hello World</b>
            [1] => Array
                (
                    [0] => Array
                        (
                            [0] => Yes am <strong> baba </strong>
                        )

                )

        )

    [c] => stdClass Object
        (
            [title] => Array
                (
                    [x] => <a>XXX</a>
                    [y] => <b>YYY</b>
                )

            [body] => <p> THis is the Body </p>
        )

)

See Live Demo

class MyClassName {
    function encode($data) {
        if (is_array($data)) {
            return array_map(array($this,'encode'), $data);
        }
        if (is_object($data)) {
            $tmp = clone $data; // avoid modifing original object
            foreach ( $data as $k => $var )
                $tmp->{$k} = $this->encode($var);
            return $tmp;
        }
        return htmlentities($data);
    }

    function decode($data) {
        if (is_array($data)) {
            return array_map(array($this,'decode'), $data);
        }
        if (is_object($data)) {
            $tmp = clone $data; // avoid modifing original object
            foreach ( $data as $k => $var )
                $tmp->{$k} = $this->decode($var);
            return $tmp;
        }
        return html_entity_decode($data);
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

this works well! I came across it and decided to use it in my own project. Thank you!
@TyBailey you can also look at stackoverflow.com/a/15034807/1226894 it uses different filters not just htmlentities
Thank you. This works well. Coincidentally, so do both of my original functions (at least for my purposes). The problem seems to be with my jquery ajax request. Somehow it's encoding the entities even though the php script is sending a decoded response. Of course I'll accept your answer because it's 100% correct for the original question. Thanks again.
I am working with SOAP Response Objects and Twig/Symfony . You just saved me a lot of time ! thnx !
I know this is a somewhat old answer, but I just want to point out that html_entitity_decode converts NULL values to strings"". Not really desirable when you're, for example, trying to insert values into your database. Suggest you add is_null($var) in there.
1

What exactly do you want to do: replace existing values with html entity decoded values or make a copy of the whole data structure with encoded values?

If you want to replace then you should pass function argument by reference:

function decode( &$data ){

If you want to make a copy -- it should work the way it is (or please explain what exactly do you mean by "the following does not work").

Comments

0

What about array-walk-recursive: http://php.net/manual/en/function.array-walk-recursive.php perhaps something like this:

function decode($data){  
    $data = html_entity_decode($data);
}
function decode_data($data){
    if(is_object($data) || is_array($data)){
       array_walk_recursive($data, 'decode');
    }else{
       $data = html_entity_decode($data);
    }
    return $data;
}

1 Comment

Also i think your first function might work if you remove "$this->"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.