大文件上的simplexml_load_string错误发生在一个系统上,而不是另一个系统上

Wes*_*rch 15 php xml 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>
Run Code Online (Sandbox Code Playgroud)

我下载了一个响应的示例文件(大约22MB),这里是我调试和理智的结果.两台服务器都运行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));
Run Code Online (Sandbox Code Playgroud)

在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>"
Run Code Online (Sandbox Code Playgroud)

远程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>"
Run Code Online (Sandbox Code Playgroud)

一些回复评论和其他信息:

  • 就我所知,XML本身似乎是有效的(它确实可以在我的系统上运行).

  • magic_quotes_runtime 肯定是关闭的.

  • 工作服务器具有libxml版本2.7.7,而另一个具有2.7.6.这真的有所作为吗?我找不到libxml更改日志,但似乎不太可能.

  • 这似乎只发生在响应/文件超过一定大小时,并且错误总是发生在倒数第二行.

  • 我没有遇到内存问题,测试脚本立即运行.

如果我知道哪些是相关的,我可以发布PHP配置的差异.知道问题可能是什么,或者知道我可能要检查的其他任何事情?

Fra*_*ila 32

libxml2的更新日志中包含"608773加入xmlGROW(丹尼尔VEILLARD)丢失的支票",这似乎是有关输入缓冲.注意:我不知道任何有关libxml2的内部,但似乎可以想象,你胳肢过2.7.6的bug修复2.7.7.

simplexml_load_file()直接使用时检查行为是否有任何不同,并尝试设置与libxml解析器相关的选项,例如

simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_COMPACT | LIBXML_PARSEHUGE)
Run Code Online (Sandbox Code Playgroud)

具体来说,您可能想要尝试该LIBXML_PARSEHUGE标志.

http://php.net/manual/en/libxml.constants.php
XML_PARSE_HUGE标志放松了解析器的任何硬编码限制.这会影响文档的最大深度或实体递归等限制,以及文本节点大小的限制.