поведение simpleXml to array выглядит странно для меня и - разбивается на 9941 элемент - PullRequest
4 голосов
/ 13 декабря 2010

EDIT3: похоже, проблема возникает на моем локальном хосте XAMPP PHP 5.3, а не на удаленных серверах с php 5.2, которые я тестировал. Все еще неясно, является ли его php или xampp (или, возможно, комбинация) причиной ошибки / EDIT3

У меня есть xml с около 12000 имен для добавления в массив. Структура xml выглядит следующим образом:

<smdusersync datetime="2010-12-13 13:51:16">
  <userstoadd>
    <User fnamn="Adam" enamn="Svensson" email="adam@darkeye.se" password="3906" />
    <User fnamn="Brooke" enamn="Jarnbjer" email="brooke@gmail.com" password="2729" />
    <User fnamn="Caesar" enamn="Carlsson" email="caesar@comhem.se" password="1668" />
   <!-- about 12000 other users -->
  </userstoadd>
  <userstoremove>
  </userstoremove>
</smdusersync>

EDIT2: я пробовал с другими примерами XML, в том числе программно сгенерированными без атрибутов и т. Д., И это не имеет значения - все та же проблема, описанная ниже ... / EDIT2

При выполнении простого цикла foreach на дочернем элементе xml userstoadd начинаются странные вещи происходит, когда я помещаю объекты в массив.

(Обратите внимание, что в приведенном ниже примере есть код, который вызывает ошибку - это бесполезный пример в любом случае ...)

Выполнение простого цикла foreach (здесь просто отправка тестового счетчика в массив) работает как ожидалось:

    $user_xml = simplexml_load_file('users.xml');
    $xml_count = $user_xml->userstoadd->children()->count();
    $users_arr = array();
    $test_count = 0;
    foreach ($user_xml->userstoadd->children() as $user) {

        array_push($users_arr, $test_count); // << Works as expected!
        $test_count++;
    }
    echo $xml_count, '/', $test_count; 

$ xml_count и $ test_count всегда имеют одно и то же значение.

Когда я делаю то же самое, за исключением того, что я помещаю простой объект в массив, все работает нормально, если число пользователей xml <= 9940: </p>

    $user_xml = simplexml_load_file('users.xml');
    $xml_count = $user_xml->userstoadd->children()->count();
    $users_arr = array();
    $test_count = 0;
    foreach ($user_xml->userstoadd->children() as $user) {
        $dummy_object = new StdClass();  // << Empty dummy object
        array_push($users_arr, $dummy_object); // << CAUSES ERROR if more than 9940 items...!
        $test_count++;
    }
    echo $xml_count, '/', $test_count; // << SHOULD BE THE SAME!

При наличии пользовательских элементов 9940 xml результат будет таким, как ожидалось 9940/9940 . НО при наличии 9941 xml пользовательских элементов результат будет 9941/19881 ! И при наличии 9942 пользовательских элементов xml вывод будет 9942/19882!

вдруг почти 10000 разницы! И содержимое пользовательских элементов, кажется, не имеет значения ... Я скопировал и переместил пользовательские элементы xml с тем же результатом ...

РЕДАКТИРОВАТЬ: Когда больше чем 9940 пунктов, это внезапно удваивается так, чтобы 9941 пунктов дал (9940 x 2) + 1 = 19881. Нет разницы при использовании одного элемента XML пользователя 12000 раз. / EDIT

Есть идеи, что здесь происходит?

Ответы [ 3 ]

2 голосов
/ 14 декабря 2010

Следующее безумие решает проблему для меня:

Вы можете закомментировать строку test(50000);.

<code><?php

test(9996); // works                         (echoes 9996/9996/9996)
test(9997); // BREAKS on my XAMPP php 5.3.1! (echoes 9997/19993/19993)
test(50000); // test with larger number

function test($items_to_create) {
    $xml_str = '<root>' . chr(13);
    for($i=0; $i<$items_to_create; $i++) {
        $xml_str .= '<item attr="t' . $i . '"/>' . chr(13);
    }
    $xml_str .= '</root>';

    $xml = new SimpleXMLElement($xml_str);

    $xml_children = $xml->children();
    $xml_count = $xml_children->count();
    $arr = array();
    $test_count = 0;

    /*
    foreach ($xml->children() as $user) {
        $dummy_object = new StdClass();
        array_push($arr, $dummy_object);
        $test_count++;
    }
    */

    for ($i=0; $i<$xml_count; $i++) {
        $dummy_object = new StdClass();
        $dummy_object->foo = $xml_children[$i]->attributes()->attr;
        array_push($arr, $dummy_object);
        $test_count++;
    }


    $arr_count = count($arr);
    echo '<br />CTRL+F for me:', $xml_count, '/', $test_count , '/', $arr_count, '<hr />';
    echo '<pre>', print_r($arr, true), '
';}?>

Это исправит это для вас?

1 голос
/ 13 декабря 2010

Хорошо, я выделил as somhow, связанный с моей настройкой XAMPP php 5.3.Протестируйте на двух разных удаленных серверах с php 5.2 и там все работает как положено.

Следующий код ломается на моем XAMPP с php 5.3.1

<?php
test(9996); // works                         (echoes 9996/9996/9996)
test(9997); // BREAKS on my XAMPP php 5.3.1! (echoes 9997/19993/19993)

function test($items_to_create) {
    $xml_str = '<root>' . chr(13);
    for($i=0; $i<$items_to_create; $i++) {
        $xml_str .= '<item />' . chr(13);
    }
    $xml_str .= '</root>';

    $xml = new SimpleXMLElement($xml_str);

    $xml_count = $xml->children()->count();
    $arr = array();
    $test_count = 0;
    foreach ($xml->children() as $user) {
        $dummy_object = new StdClass();
        array_push($arr, $dummy_object);
        $test_count++;
    }
    $arr_count = count($arr);
    echo "<br/>", $xml_count, '/', $test_count , '/', $arr_count;
}
1 голос
/ 13 декабря 2010

Как вы описываете, я не вижу никакого отношения к обработке XML. Пожалуйста, запустите этот код, чтобы проверить:

$xml_count = 9950;
$users_arr = array();
$test_count = 0;
foreach (range(0, $xml_count) as $user) {
    $dummy_object = new StdClass();
    array_push($users_arr, $dummy_object);
    $test_count++;
}
echo $xml_count, '/', $test_count, '/', count($users_arr);

Он должен напечатать число 9950 три раза. Если это не так на вашем компьютере, ваш PHP сломан.

...