将unset
函数与SimpleXML解码数组结合使用时,我发现了一个奇怪的问题。应用于此类数组的索引之一(数字索引)的unset
函数似乎重置了数组索引。
这对我来说似乎是一种无证的行为(或者更像是一个错误)。有没有人得到解释为什么对SimpleXML阵列进行“特殊的重建索引”处理?
这是一个解释它的测试用例。
<?php
$a = array( 1, 2, 3, 4 );
echo "Regular array, before unset(\$a[1]): " . print_r( $a, 1 );
unset( $a[1] );
echo "Regular array, after unset(\$a[1]): " . print_r( $a, 1 );
$xml = simplexml_load_string( <<<EOT
<?xml version="1.0" encoding="UTF-8"?>
<root>
<node>1</node>
<node>2</node>
<node>3</node>
<node>4</node>
<node>5</node>
</root>
EOT
);
echo "SimpleXML array, before unset(\$a[1]): " . print_r( $xml, 1 );
unset( $xml->node[1] );
echo "SimpleXML array, after unset(\$a[1]): " . print_r( $xml, 1 );
我得到的输出是,
Regular array, before unset($a[1]): Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
)
Regular array, after unset($a[1]): Array
(
[0] => 1
[2] => 3
[3] => 4
)
SimpleXML array, before unset($a[1]): SimpleXMLElement Object
(
[node] => Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
)
)
SimpleXML array, after unset($a[1]): SimpleXMLElement Object
(
[node] => Array
(
[0] => 1
[1] => 3
[2] => 4
[3] => 5
)
)
答案 0 :(得分:2)
如果数组实际上是一个对象而不是一个简单的数组,并且该类有一个魔术__unset()方法定义,那么脚本编写者可能会选择故意重新索引元素,以便键保持顺序...有益于那些喜欢使用for($i = 0; $i < count($nodes); $i++)
而不是foreach($nodes as $node)
循环“数组”的程序员。
我认为SimpleXML是用C而不是PHP编写的,但是同样的原则可能已用于防止for($i = 0; $i < count($nodes); $i++)
编码器使用时出现“破坏”。
答案 1 :(得分:2)
原因是访问$xml->node
并不能提供实际数组。 $xml->node[1]
返回一个SimpleXMLElement实例,它有一个魔术方法__unset
,当你取消它时会调用它。它不使用PHP的默认未设置行为,因为它对数组使用。
答案 2 :(得分:0)
在您的代码中
unset( $xml->node[1] );
不
unset($a[1])
就像你在输出中描述的那样。
你做的unset( $xml->node[1] );
将是:
unset($a[node][1])
因此它是正确的。