0

以下是从 XML 文档转换而来的数组的 print_r:

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

对于上面的数组, sizeof($myarray[layer1][item]) 应该返回 1,但它返回 4。如果有多个“项目”项目,我会得到正确数量的“项目”项目。无论我使用“sizeof”还是“count”,都会发生同样的错误。当只有一项时,如何让 PHP 返回“1”?

因此,如果有一个项目,我无法使用 array[layer1][item][0][item-name] 访问 item-name,我必须使用 array[layer1][item][item-name]。

4

1 回答 1

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);
    }
}

这应该会阻止您的数组堆叠......但是,如果您的代码中有任何其他部分依赖于先前的结构,则此更改可能会破坏该代码。

于 2012-10-09T00:17:46.960 回答