2013-02-13 110 views
1

我试图构建一个将html_entity_decode应用于对象和数组的函数。由于我事先不知道结构,并且子属性也可以是对象或数组,所以一个简单的递归函数似乎是要走的路。我无法弄清楚,为什么下面不工作:将html_entity_decode应用于递归对象和数组

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; 
} 

我也曾尝试以下,这不工作之一:

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; 
} 

无论是功能上的任何数据影响。我究竟做错了什么?

回答

9

的主要问题是,你正试图与对象的工作像数组is_object($data) || is_array($data)真的不会,除非你的工作转换objectarray

等问题的基础上不正确的变量名,而不是返回正确的变量可以尝试

$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); 

编码数组

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; 
     ) 

) 

解码阵列

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); 
    } 
} 
+1

这个效果很好!我遇到它并决定在我自己的项目中使用它。谢谢! – 2013-03-02 05:54:34

+0

@TyBailey你也可以看看http://stackoverflow.com/a/15034807/1226894它使用不同的过滤器不只是'htmlentities' – Baba 2013-03-02 09:48:00

+0

谢谢。这很好。巧合的是,我的两个原始功能(至少为了我的目的)也是如此。这个问题似乎与我的jquery ajax请求。不知何故,即使PHP脚本正在发送已解码的响应,它也会对实体进行编码。当然,我会接受你的答案,因为它对于原始问题是100%正确的。再次感谢。 – 2013-03-07 06:22:30

0

什么阵列步行递归: http://php.net/manual/en/function.array-walk-recursive.php 或许是这样的:

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

另外我认为你的第一个功能可能会工作,如果你删除“$ this->” – 2013-02-13 20:25:51

1

你想要做的究竟是什么:替换HTML entit现有值y解码值或使用编码值复制整个数据结构?

如果你想更换,那么你应该通过引用传递函数参数:

function decode(&$data){ 

如果你想使一个副本 - 它应该工作的方式是(或请解释究竟是什么你的意思通过“以下不起作用”)。