2010-08-06 67 views
2

unset函數與SimpleXML解碼數組結合使用時,我發現了一個奇怪的問題。 unset函數應用於這樣一個數組的索引之一(數字索引),似乎會重置數組索引。在PHP中,在什麼情況下unset()調用會重置數組索引?

這看起來像一個無證的行爲給我(或更像一個錯誤)。有沒有人得到解釋爲什麼SimpleXML數組有一個「特殊reindexing」處理?

下面是一個解釋它的測試案例。

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

) 

回答

2

如果數組實際上是一個對象而不是一個簡單數組,並且類中定義了一個magic __unset()方法,那麼腳本編程人員可能會選擇故意重新索引這些元素,以便這些鍵保持順序...有益對於喜歡使用for($i = 0; $i < count($nodes); $i++)而不是foreach($nodes as $node)循環訪問「數組」的編碼人員。

我認爲SimpleXML是用C而不是PHP編寫的,但是當for($i = 0; $i < count($nodes); $i++)編碼器使用相同的原則時可能已經被應用來防止「破損」。

0

在你的代碼做

unset($xml->node[1]); 

unset($a[1]) 

就像你在你的輸出描述。

unset($xml->node[1]);你做什麼,應該是:

unset($a[node][1]) 

因此它是正確的。

2

原因是訪問$xml->node不會給你一個實際的數組。 $xml->node[1]會返回一個SimpleXMLElement的實例,它有一個魔術方法__unset,當您取消設置時會調用該方法。它不像使用PHP的默認未設置行爲那樣使用數組。

相關問題