php foreach多维数组递归不工作?

php foreach多维数组递归不工作?,php,recursion,multidimensional-array,foreach,associative-array,Php,Recursion,Multidimensional Array,Foreach,Associative Array,我最后一个问题的后续问题: 我将此数组作为输入: Array ( [0] => apl_struct Object ( [funcname] => say [args] => Array ( [0] => Array ( [0] => apl_struct Object ( [

我最后一个问题的后续问题:

我将此数组作为输入:

Array
(
  [0] => apl_struct Object
    (
      [funcname] => say
      [args] => Array
        (
          [0] => Array
            (
              [0] => apl_struct Object
                (
                  [funcname] => text
                  [args] => Array
                    (
                      [value] => hello
                    )
                )
            )
        )
    )
)
我现在有两个功能为我工作。 一个是func,仅用于获取关联数组中的下一个键/值。 没有一个next()、prev()等在索引数组中对我有效:

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;}
}
函数getnext($array,$key){ $keys=数组\ U键($array); if((false!==($p=array_search($key,$keys))&($p$keys[+$p],'value'=>$array[$keys[$p]]); }else{return false;} } 下一个函数是我的执行器或构造函数。他为我创建了一个半xmlstruct。 我尝试添加递归以跳过数字键。它们显然是胡说八道,可以跳过

然后我想检查非数字键的所有值是否都是数组。 若它是一个数组,那个么它指示要遵循的参数,并且输出应该是:INPUT

如果不是,它要么是functionname(funcname),要么确实是一个真正的值,比如“hello”

函数arr2xml($array,$level=1,$pos=1){
$xml='';
foreach($key=>$value的数组){
如果(is_object($value)){$value=get_object_vars($value);}//将对象转换为数组
如果(是数字($key)){
$xml.=arr2xml($value);
}否则{
如果(!是_数组($value)){
交换机($key){
案例“funcname”:
$nextkey=getnext($array,$key);
$xml.=str\u repeat(“\t”,$level)。“\n”;
$xml.=arr2xml($nextkey['value'],$level++);
$xml.=str\u repeat(“\t”,$level)。“\n”;
打破
案例“值”:
$xml.=str\u repeat(“\t”,$level)。“\t$value\n”;
打破
}
}否则{
$xml.=str\u repeat(“\t”,$level)。“\n\t”;
$xml.=arr2xml($value、$level++、$pos++);
$xml.=str\u repeat(“\t”,$level)。“\n”;
}
}
}
返回$xml;
}
但到目前为止,我从中得到的是: 函数名已正确插入。 它是说和文本。 此外,在某些情况下,-标记和值会正确执行

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

你好
你好
你好
你好
对我来说,递归似乎没有真正起作用。我是不是遗漏了什么? 我试图从前面提到的帖子中重建它

我还想知道我在这里得到的多重输出。 标签似乎填对了,但实际的安排对我来说相当混乱

我希望输出如下所示:

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

你好
提前感谢

TL;博士 它是(完全多余的函数)
getnext()
arr2xml()
递归方式的组合。我在这里提供了一个
arr2xml()
replacement函数,它可以执行您想要的操作,而不需要
getnext()

下面将详细描述代码中的错误,以及我建议如何修复它

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

  foreach ($array as $key => $value) {
    if (is_object($value)) {
      $value = get_object_vars($value);
    }
    if (is_numeric($key)) {
      $xml .= arr2xml($value, $level+1);
      continue;
    } else {
      if (!is_array($value)) {
        switch ($key) {
          case 'funcname':
            array_shift($array);
            $xml .= str_repeat("    ", $level) . "<apl:$value>\n";
            $xml .= arr2xml($array, $level+1);
            $xml .= str_repeat("    ", $level) . "</apl:$value>\n";
            return $xml;
          case 'value':
            $xml .= str_repeat("    ", $level) . "    $value\n";
            return $xml;
        }
      } else {
          $xml .= str_repeat("    ", $level) . "<$key pos='$pos'>\n    ";
          $xml .= arr2xml($value, $level+1, $pos+1);
          $xml .= str_repeat("    ", $level) . "</$key>\n";
          return $xml;
      }
    }
  }

  return $xml;
}
然后在该数组(
$p=array\u search($key,$keys)
)中找到
'funcname'
,并创建一个仅包含数组中下一项值的新数组:

return array('key' => $keys[++$p], 'value' => $array[$keys[$p]]);
结果是一个数组不再包含
'args'
键:

array(2) {
  ["key"]=>
  string(4) "args"
  ["value"]=>
  array(1) {
    [0]=>
    array(1) {
      [0]=>
      object(apl_struct)#1 (2) {
        ["funcname"]=>
        string(4) "text"
        ["args"]=>
        array(1) {
          ["value"]=>
          string(5) "hello"
        }
      }
    }
  }
}
因此,您将永远无法获得所希望的标记,因为数据结构已被
getnext()
破坏,从而删除您希望找到的密钥以构造它

重复值可以通过先前从内部递归返回来解决。现在,您正在递归,处理“内部”节点,然后返回顶部并再次处理它们


相反,我们可以完全删除
getnext
(因为它甚至不能满足您的需要),我们可以使用它来丢弃数组中最左边的值。然后,我们继续像平常一样处理
$array

经过一段时间后,我为我的问题想出了这个解决方案:

function apl2xml($array, $tlevel = 0) {
    $ret = '';
    $ret .= str_repeat("\t", $tlevel) . "<apl>\n";

    foreach ($array as $key => $value) {
        $ret .= $this->aplstruct2xml($value, $tlevel + 1);
    }

    $ret .= str_repeat("\t", $tlevel) . "</apl>\n";
    return $ret;
}

function aplstruct2xml($apl_struct, $tlevel = 0) {
    $ret = '';

    if ($apl_struct->funcname == 'text') {
        $ret .= str_repeat("\t", $tlevel) . "<text>\n";

        $ret .= str_repeat("\t", $tlevel);
        $ret .= $apl_struct->args[0] . "\n";

        $ret .= str_repeat("\t", $tlevel) . "</text>\n";
    } else {
        $ret .= str_repeat("\t", $tlevel) . "<aplfunc:{$apl_struct->funcname}>\n";

        foreach ($apl_struct->args as $key => $value) {
            $ret .= str_repeat("\t", $tlevel + 1) . "<arg pos='$key'>\n";
            $ret .= $this->apl2xml($value, $tlevel + 2);
            $ret .= str_repeat("\t", $tlevel + 1) . "</arg>\n";
        }

        $ret .= str_repeat("\t", $tlevel) . "</aplfunc:{$apl_struct->funcname}>\n";
    }
    return $ret;
}
函数apl2xml($array,$tlevel=0){ $ret=''; $ret.=str\u repeat(“\t”,$t级别)。“\n”; foreach($key=>$value的数组){ $ret.=$this->aplstruct2xml($value,$t级别+1); } $ret.=str\u repeat(“\t”,$t级别)。“\n”; 返回$ret; } 函数aplstruct2xml($apl_struct,$tlevel=0){ $ret=''; 如果($apl_struct->funcname=='text'){ $ret.=str\u repeat(“\t”,$t级别)。“\n”; $ret.=str_repeat(“\t”,$t水平); $ret.=$apl\U结构->参数[0]。“\n”; $ret.=str\u repeat(“\t”,$t级别)。“\n”; }否则{ $ret.=str\u repeat(“\t”,$tlevel)。“funcname}>\n”; foreach($apl_struct->args as$key=>value){ $ret.=str\u repeat(“\t”,$t级别+1)。“\n”; $ret.=$this->apl2xml($value,$t级别+2); $ret.=str\u repeat(“\t”,$t级别+1)。“\n”; } $ret.=str\u repeat(“\t”,$tlevel)。“funcname}>\n”; } 返回$ret; } 事实证明,我根本不需要任何递归


所谓的apl只是由一个apl_结构组成,其中可能包含更多apl/apl_结构

请查看粘贴的代码。应该
xml=''
be
xml=''?和
$xml.=>arr2xml($value)应该是
$xml.=arr2xml($value)?输入的结构不一致-这是故意的吗?例如,您的一个“arg”有一个数组,其中包含一个数组,该数组最终包含一个实际对象作为其第一个元素。其他参数只是一个数组,字符串作为第一个元素。谢谢。这很有效。我完全没有通过调用getnext()来创建新的、已损坏的值。array_shift()现在就完成了。我记得曾经尝试过array_shift(),结果输出完全中断。似乎函数在另一个点是错误的
array(2) {
  ["key"]=>
  string(4) "args"
  ["value"]=>
  array(1) {
    [0]=>
    array(1) {
      [0]=>
      object(apl_struct)#1 (2) {
        ["funcname"]=>
        string(4) "text"
        ["args"]=>
        array(1) {
          ["value"]=>
          string(5) "hello"
        }
      }
    }
  }
}
function apl2xml($array, $tlevel = 0) {
    $ret = '';
    $ret .= str_repeat("\t", $tlevel) . "<apl>\n";

    foreach ($array as $key => $value) {
        $ret .= $this->aplstruct2xml($value, $tlevel + 1);
    }

    $ret .= str_repeat("\t", $tlevel) . "</apl>\n";
    return $ret;
}

function aplstruct2xml($apl_struct, $tlevel = 0) {
    $ret = '';

    if ($apl_struct->funcname == 'text') {
        $ret .= str_repeat("\t", $tlevel) . "<text>\n";

        $ret .= str_repeat("\t", $tlevel);
        $ret .= $apl_struct->args[0] . "\n";

        $ret .= str_repeat("\t", $tlevel) . "</text>\n";
    } else {
        $ret .= str_repeat("\t", $tlevel) . "<aplfunc:{$apl_struct->funcname}>\n";

        foreach ($apl_struct->args as $key => $value) {
            $ret .= str_repeat("\t", $tlevel + 1) . "<arg pos='$key'>\n";
            $ret .= $this->apl2xml($value, $tlevel + 2);
            $ret .= str_repeat("\t", $tlevel + 1) . "</arg>\n";
        }

        $ret .= str_repeat("\t", $tlevel) . "</aplfunc:{$apl_struct->funcname}>\n";
    }
    return $ret;
}