ошибки строки загрузки simplexml в больших файлах происходят в одной системе, но не в другой

Я имею дело с сторонней библиотекой PHP, которую я не могу редактировать, и она работает нормально почти год. Он использует simplexml_load_string на ответ от удаленного сервера. В последнее время он задыхается от больших реакций. Это канал данных для списков недвижимости, и формат выглядит примерно так:

<?xml version="1.0"?>
<RETS ReplyCode="0" ReplyText="Operation Successful Reference ID: 9bac803e-b507-49b7-ac7c-d8e8e3f3aa89">
<COUNT Records="9506" />
<DELIMITER value="09" />
<COLUMNS>   sysid   1   2   3   4   5   6   </COLUMNS>
<DATA>  252370080   Residential 0.160   No  ADDR0   06051</DATA>
<DATA>  252370081   Residential 0.440   Yes ADDR0   06043</DATA>
<DATA>  252370082   Residential 1.010   No  ADDR0   06023</DATA>
<DATA>More tab delimited text</DATA>
<!-- snip 9000+ lines -->
</RETS>

Я загрузил пример файла ответа (около 22 МБ), вот где я закончил с моей отладкой и здравомыслием. Оба сервера работают под управлением PHP версии 5.3.8, но обратите внимание различный результат. Я уверен, что оба файла одинаковы (я полагаю, что разные размеры файлов, strlen и последние 50 символов могут быть объяснены новыми строками Windows, имеющими дополнительный символ возврата каретки). Тестовый скрипт:

error_reporting(-1);
ini_set('display_errors', 1);
$file = 'error-example.xml';
$xml = file_get_contents($file);

echo 'filesize:              ';
var_dump(filesize($file));

echo 'strlen:                ';
var_dump(strlen($xml));

echo 'simplexml object?      ';
var_dump(is_object(simplexml_load_string($xml)));

echo 'Last 50 characters:    ';
var_dump(substr($xml, -50));

вывод локально на Windows:

filesize:              int(21893604)
strlen:                int(21893604)
simplexml object?      bool(true)
Last 50 characters:    string(50) "RD DR    CT  Watertown   203-555-5555            </DATA>
</RETS>"

вывод на удаленный сервер UNIX:

filesize:              int(21884093)
strlen:                int(21884093)
simplexml object?      
Warning: simplexml_load_string(): Entity: line 9511: parser error : internal error in /path/to/test.php on line 19

Warning: simplexml_load_string(): AULTED CEILING IN FOYER, BRICK FP IN FR, NEW FLOORING IN LR DR FR FOYER KITCHEN  in /path/to/test.php on line 19

Warning: simplexml_load_string():                                                                                ^ in /path/to/test.php on line 19

Warning: simplexml_load_string(): Entity: line 9511: parser error : Extra content at the end of the document in /path/to/test.php on line 19

Warning: simplexml_load_string(): AULTED CEILING IN FOYER, BRICK FP IN FR, NEW FLOORING IN LR DR FR FOYER KITCHEN  in /path/to/test.php on line 19

Warning: simplexml_load_string():                                                                                ^ in /path/to/test.php on line 19
bool(false)
Last 50 characters:    string(50) "ORD DR   CT  Watertown   203-555-5555            </DATA>
</RETS>"

некоторые ответы на комментарии и дополнительная информация:

  • сам XML кажется действительным, насколько Я могу сказать (и это тут работа над моей системой).

  • magic_quotes_runtime определенно не сходится.

  • рабочий сервер имеет libxml версии 2.7.7 в то время как другой имеет 2.7.6. Может ли это что-то изменить? Я не смог найти журнал изменений libxml, но это кажется маловероятным.

  • это, кажется, происходит только тогда, когда ответ / файл превышает определенный размер, и ошибка всегда возникает в предпоследнем линия.

  • у меня нет проблем с памятью, тестовый скрипт запускается мгновенно.

есть различия в конфигурациях PHP, которые я могу опубликовать, если бы знал, какие из них актуальны. Есть идеи, в чем может быть проблема, или знаете что-нибудь еще, что я мог бы проверить?

3 ответов


на библиотеки libxml2 изменений содержит "608773 добавить недостающий чек в xmlGROW (Daniel Veillard)", что, по-видимому, связано с буферизацией ввода. Заметьте, я не знаю что-нибудь о libxml2 internals, но кажется возможным, что вы щекотали ошибку 2.7.6, исправленную в 2.7.7.

Проверьте, отличается ли поведение при использовании simplexml_load_file() напрямую и попробуйте установить параметры, связанные с анализатором libxml, например,

simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_COMPACT | LIBXML_PARSEHUGE)

в частности, вы можете попробовать LIBXML_PARSEHUGE флаг.

http://php.net/manual/en/libxml.constants.php
XML_PARSE_HUGE флаг расслабляет любое фиксированное ограничение парсера. Это влияет на такие ограничения, как максимальная глубина документа или рекурсия сущности, а также ограничения размера текстовых узлов.


ваш XML недопустим и должен вызвать проблему в обоих случаях.

У вас должен быть только один корень.

ie. Все должно быть внутри тегов:

<?xml version="1.0"?>
<RETS>
    ...
</RETS>

у вас есть несколько корней в вашем XML, что вызовет проблему : -)

попробуйте обернуть все это в корневой узел и посмотреть, работает ли он.

<?xml version="1.0"?>
<rootNode>
    <RETS>
    ...
    </RETS>
    <count bla="99" />
</rootNode>

Я не уверен, будет ли это разница в libxml или другой уровень отчетов об ошибках, позволяющий ему работать на одном и не другой, но это похоже на проблему для меня.


мой XMLSpy подтвердил, что ваш XML-файл (который я загрузил из ссылки, которую вы предоставили) не имеет проблем и хорошо сформирован.

одна потенциальная проблема, однако, заключается в том, что атрибут "encoding" отсутствует в преамбуле XML: в зависимости от вашей версии libxml2, я думаю, что следующий сценарий может быть возможен: Сервер проверяет атрибут кодировки, при отсутствии которого сервер возвращается к некоторому значению по умолчанию (настройка конфигурации). Возможно, более старые версии библиотеки не проверьте спецификацию.

пожалуйста, Также см. Эту ссылку, у них была аналогичная проблема кодирования с libxml: https://stackoverflow.com/questions/4724241/utf-8-problems-with-php-dom-on-debian-server

суть которого заключается в том, что обновление вашей библиотеки libxml действительно может решить проблему. В качестве альтернативы, возможно, стоит проверить настройку кодировки по умолчанию в конфигурации.

согласно моему XMLSpy, файл кодируется utf-8-как тест, возможно, стоит проверить, если указать

<?xml version="1.0" encoding="UTF-8"?>

поскольку преамбула файла останавливает ваш сервер Unix от удушения.