2012-10-08 60 views
0

以下是從XML文檔轉換的陣列的的print_r:不正確的PHP的sizeof或計數

Array 
    (
     [layer1] => Array 
      (
       [item] => Array 
        (
         [item-id] => 1886731 
         [item-name] => Bad Dog 
         [category] => pets 
         [link] = http://www.baddog.com/ 
        ) 
      [total-matched] => 1 
     ) 
    ) 

對於上述陣列,的sizeof($ myArray的[層1] [項目])應該返回1,但它返回4.如果有多個項目,我會得到正確數量的「項目」項目。無論我使用「sizeof」還是「count」,都會發生同樣的錯誤。當只有一個項目時,如何讓PHP返回「1」?因此,如果有一個項目,我不能訪問使用數組[層1] [項目] [0] [項目名稱]的項目名稱,我必須使用數組[層1] [項目] [項目-名稱]。

+2

你用什麼來構造你的數組結構?這是什麼導致你的問題。不是'sizeof'或'count'。 – Pebbl

+0

如果你真的使用裸字符串(即'$ array [layer1]'而不是'$ array ['layer1']'',你首先應該改變它,參見[doc](http:// php。 net/manual/en/language.types.array.php),搜索「爲什麼是$ foo [bar]錯誤?」。 – fvu

+1

'sizeof'告訴你數組中有多少個元素。簡單和基本的功能是完美的工作,你只是簡單地使用它,爲了幫助你,我們需要你看看你的代碼 – deceze

回答

6

之間存在天壤之別:

$array1 = array(
    'layer1' => array(
    'item' => array(
     '0' => array(
     'item-id' => 123123, 
     'item-name' => 'Bad Dog', 
     'category' => 'pets', 
     'link' => 'http://www.baddog.com/', 
    ), 
    ) 
) 
); 

和:

$array2 = array(
    'layer1' => array(
    'item' => array(
     'item-id' => 123123, 
     'item-name' => 'Bad Dog', 
     'category' => 'pets', 
     'link' => 'http://www.baddog.com/', 
    ) 
) 
); 

它們基本上是不同的結構,和PHP是正確的返回如下:

count($array1['layer1']['item']); 
/// = 1 (count of items in the array at that point) 

count($array2['layer1']['item']); 
/// = 4 (count of items in the array at that point) 

如果您希望獲得對您的應用有意義的['layer1']['item']的計數,您將始終需要['layer1']['item']爲包含多個陣列結構的陣列...即,如上面的$array1。這就是爲什麼我問什麼是生成你的數組結構的原因,因爲 - 無論它是什麼 - 它基本上是智能地堆疊你的數組數據,這取決於項目的數量,這是你不想要的。

可以引起陣列以這種方式堆疊

代碼通常看起來類似於以下:

/// $array = array(); /// this is implied (should be set elsewhere) 

$key = 'test'; 
$newval = 'value'; 

/// if we are an array, add a new item to the array 
if (is_array($array[$key])) { 
    $array[$key][] = $newval; 
} 
/// if we have a previous non-array value, convert to an array 
/// containing the previous and new value 
else if (isset($array[$key])) { 
    $array[$key] = array($array[$key],$newval); 
} 
/// if nothing is set, set the $newval 
else { 
    $array[$key] = $newval; 
} 

基本上如果你保持調用上面的代碼,並且在每次運行後追查,你將看到以下結構建立:

$array == 'value'; 

然後

$array == array(0 => 'value', 1 => 'value'); 

然後

$array == array(0 => 'value', 1 => 'value', 2 => 'value'); 

這是造成問題的第一步,即$array = 'value';位。如果您修改代碼稍微可以擺脫這樣的:

/// $array = array(); /// this is implied (should be set elsewhere) 
$key = 'test'; 
$newval = 'value'; 

/// if we are an array, add a new item to the array 
if (is_array($array[$key])) { 
    $array[$key][] = $newval; 
} 
/// if nothing is set, set the $newval as part of an subarray 
else { 
    $array[$key] = array($newval); 
} 

正如你可以看到我所做的就是刪除itermediate if statement,並確保當我們發現沒有初始值設定,我們始終創建一個數組。上面將創建一個結構,您可以隨時計數並知道您推送到陣列的項目數量。

$array == array(0 => 'value'); 

然後

$array == array(0 => 'value', 1 => 'value'); 

然後

$array == array(0 => 'value', 1 => 'value', 2 => 'value'); 

更新

啊,我是這麼認爲的。所以這個數組是從XML生成的。在這種情況下,我收集你正在使用預定義的庫來做到這一點,所以修改代碼是不可能的。因此,正如其他人已經說過,你最好的辦法是使用可用於PHP的許多XML解析庫之一:

http://www.uk.php.net/simplexml

http://www.uk.php.net/dom

當使用這些系統可以保留更多的對象結構的哪應該更容易計數。上述兩種方法都支持xpath符號,可以讓您在不需要保存任何數據的情況下對項目進行計數。

更新2

出你給的功能,這是導致你的陣列,導致該問題的方式協議棧部分:

$children = array(); 
$first = true; 
foreach($xml->children() as $elementName => $child){ 
    $value = simpleXMLToArray($child,$attributesKey, $childrenKey,$valueKey); 
    if(isset($children[$elementName])){ 
     if(is_array($children[$elementName])){ 
      if($first){ 
       $temp = $children[$elementName]; 
       unset($children[$elementName]); 
       $children[$elementName][] = $temp; 
       $first=false; 
      } 
      $children[$elementName][] = $value; 
     }else{ 
      $children[$elementName] = array($children[$elementName],$value); 
     } 
    } 
    else{ 
     $children[$elementName] = $value; 
    } 
} 

修改將是:

$children = array(); 
foreach($xml->children() as $elementName => $child){ 
    $value = simpleXMLToArray($child,$attributesKey, $childrenKey,$valueKey); 
    if(isset($children[$elementName])){ 
     if(is_array($children[$elementName])){ 
      $children[$elementName][] = $value; 
     } 
    } 
    else{ 
     $children[$elementName] = array($value); 
    } 
} 

這應該阻止你的數組堆棧...但是,如果你有任何其他部分的代碼塔t依賴於以前的結構,這種改變可能會破壞該代碼。

+0

感謝您的詳細回覆。你把這些例子儘快解決了! :) 我正在使用這個功能:http://www.php.net/manual/en/book.simplexml.php#105697 – 0pt1m1z3

+0

沒問題,它總是最好一次一步地通過interations :)希望我剛剛添加的修改後的代碼應該排除你的問題......? – Pebbl

+0

不幸的是,堆疊所有子數組需要進行太多的代碼更改。有沒有辦法只是數組[層1] [項]是總是堆疊的水平?所以不是[layer1] [item],我總是有[layer1] [item] [0]。這需要在其他地方進行最少量的代碼更改... – 0pt1m1z3