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」のどちらを使用しても、同じエラーが発生します。アイテムが1つしかないときにPHPに「1」を返すにはどうすればよいですか?

したがって、アイテムが 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 解析ライブラリの 1 つを使用することです。

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 に答える