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函数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=''
bexml=''代码>?和$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;
}