dongyidao1461 2014-10-22 22:59
浏览 139
已采纳

php foreach多维数组递归无法正常工作?

Some kind of followup to my last question: for loop - move deeper on numeric key in multidimensional array

I have this array as input:

Array
(
  [0] => apl_struct Object
    (
      [funcname] => say
      [args] => Array
        (
          [0] => Array
            (
              [0] => apl_struct Object
                (
                  [funcname] => text
                  [args] => Array
                    (
                      [value] => hello
                    )
                )
            )
        )
    )
)

I now have 2 functions working for me. One is a func only for getting the next key/value in an associative array. None of the next(), prev(), etc. were working for me like on indexed arrays:

function getnext($array, $key) {
  $keys = array_keys($array);

  if ((false !== ($p = array_search($key, $keys))) && ($p < count($keys) - 1)) {
    return array('key' => $keys[++$p], 'value' => $array[$keys[$p]]);
  } else {return false;}
}

The next function is my executer or constructer. he creates a semi-xmlstruct for me. I tried to add recursion for skipping the numeric key. They're obviously nonsense and can be skipped.

I then want to check if all the values of the non-numeric keys are arrays or not. If it is an array it indicates arguments to be followed and output should look like: INPUT.

If not, it's either the functionname (funcname) or indeed a real value for us like "hello".

function arr2xml($array, $level = 1, $pos = 1) {
  $xml = '';

  foreach ($array as $key => $value) {
    if (is_object($value)) {$value = get_object_vars($value);}// convert object to array
      if (is_numeric($key)) {
        $xml .= arr2xml($value);
      } else {
        if (!is_array($value)) {
          switch ($key) {
            case 'funcname':
              $nextkey = getnext($array, $key);
              $xml .= str_repeat("\t", $level) . "<apl:$value>
";
              $xml .= arr2xml($nextkey['value'], $level++);
              $xml .= str_repeat("\t", $level) . "</apl:$value>
";
              break;
            case 'value':
              $xml .= str_repeat("\t", $level) . "\t$value
";
              break;
          }
        } else {
            $xml .= str_repeat("\t", $level) . "<$key pos='$pos'>
\t";
            $xml .= arr2xml($value, $level++, $pos++);
            $xml .= str_repeat("\t", $level) . "</$key>
";
        }
      }
  }

return $xml;
}

but what I am getting out of this so far is this: the function name was inserted right. it is say and text. also, in some wild circumstances, the -tag and the value are executed properly.

<apl:say>
<apl:text>
    hello
    </apl:text>
    <args pos='1'>
        hello
      </args>
    </apl:say>
    <args pos='1'>
    <apl:text>
    hello
    </apl:text>
    <args pos='1'>
        hello
      </args>
      </args>
</xml>

for me it looks like the recursion isn't really working. Am i missing something here? I've tried to rebuild it from previous mentioned post.

Also I'm wondering about the multiple output I am getting here. The tags seem to get filled right, but the actual arrangement is quite confusing for me.

I was expecting the output to look like this:

<apl:say>
  <args pos='1'>
    <apl:text>
      <args pos='1'>
      hello
      </args>
    </apl:text>
  </args>
</apl:say>

Thanks in advance

  • 写回答

2条回答 默认 最新

  • dongluan1901 2015-02-04 12:28
    关注

    after some time spent i came up with this solution for my problem:

    function apl2xml($array, $tlevel = 0) {
        $ret = '';
        $ret .= str_repeat("\t", $tlevel) . "<apl>
    ";
    
        foreach ($array as $key => $value) {
            $ret .= $this->aplstruct2xml($value, $tlevel + 1);
        }
    
        $ret .= str_repeat("\t", $tlevel) . "</apl>
    ";
        return $ret;
    }
    
    function aplstruct2xml($apl_struct, $tlevel = 0) {
        $ret = '';
    
        if ($apl_struct->funcname == 'text') {
            $ret .= str_repeat("\t", $tlevel) . "<text>
    ";
    
            $ret .= str_repeat("\t", $tlevel);
            $ret .= $apl_struct->args[0] . "
    ";
    
            $ret .= str_repeat("\t", $tlevel) . "</text>
    ";
        } else {
            $ret .= str_repeat("\t", $tlevel) . "<aplfunc:{$apl_struct->funcname}>
    ";
    
            foreach ($apl_struct->args as $key => $value) {
                $ret .= str_repeat("\t", $tlevel + 1) . "<arg pos='$key'>
    ";
                $ret .= $this->apl2xml($value, $tlevel + 2);
                $ret .= str_repeat("\t", $tlevel + 1) . "</arg>
    ";
            }
    
            $ret .= str_repeat("\t", $tlevel) . "</aplfunc:{$apl_struct->funcname}>
    ";
        }
        return $ret;
    }
    

    turns out that i did not need any recursion at all..

    the so called apl just consisted of an apl_struct which could contain more apl's/apl_struct's

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 程序不包含适用于入口点的静态Main方法
  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记