在 simplexmlelement 上 foreach 中的无限循环

Mat*_*eve 5 php foreach xdebug infinite-loop

我面临一个特殊的问题,因为我没有找到太多参考资料。我发现simpleXMLElement 属性和 foreach描述了同样的问题,但一年没有答案,也没有任何答案。

对于一些上下文,我正在尝试使用PHPOffice/PHPExcel,并且在加载xlsx文件时,此框架simplexmlelement在 364 到 376 行上循环Excel2007.php,可在https://github.com/PHPOffice/PHPExcel/blob/1.8/Classes /PHPExcel/Reader/Excel2007.php,这里提取了其中的几行(我添加了 var_dump 和 echo):

foreach ( $colourScheme as $k => $xmlColour ) {
    var_dump ( $xmlColour ); echo 'NEWVAR';
    $themePos = array_search ( $k, $themeOrderArray );
    if (! $themePos) {
        $themePos = $themeOrderAdditional ++;
    }
    if (isset ( $xmlColour->sysClr )) {
        $xmlColourData = $xmlColour->sysClr->attributes ();
        $themeColours [$themePos] = $xmlColourData ['lastClr'];
    } elseif (isset ( $xmlColour->srgbClr )) {
        $xmlColourData = $xmlColour->srgbClr->attributes ();
        $themeColours [$themePos] = $xmlColourData ['val'];
    }
}
Run Code Online (Sandbox Code Playgroud)

$colourScheme变种是一个SimpleXMLElement,它包含12 SimpleXMLElements,所有放入系统12有一个SimpleXMLElement0作为孩子,除了一个有"srgbClr"

当我尝试调试它时,$kvar 在循环的 2 次迭代中得到更新,然后不再改变(并且在 中有 12 次出现$colorScheme),因此无限循环(或至少直到时间限制,我尝试了很长的价值)。

如果我评论我的以下几行php.ini(我正在使用 64b 版本的wampServer,在 Windows 7 上,使用 eclisePDT 调试图标作为 Web 应用程序开始调试),无限循环似乎没有发生,并且文件似乎很好转变。

; XDEBUG Extension

zend_extension = "D:/path/to/wamp/bin/php/php5.5.12/zend_ext/php_xdebug-2.2.5-5.5-vc11-x86_64.dll"
;
[xdebug]
xdebug.remote_enable = on
xdebug.remote_host = "localhost"
xdebug.remote_port = 9000
xdebug.remote_handler = "dbgp"
xdebug.remote_mode = req
xdebug.profiler_enable = On
xdebug.profiler_enable_trigger = off
xdebug.profiler_output_name = cachegrind.out.%t.%p
xdebug.profiler_output_dir = "D:/path/to/tmp/tmp"
xdebug.show_local_vars = on
xdebug.collect_params = on
Run Code Online (Sandbox Code Playgroud)

编辑:更多信息。php.ini在我在 eclipse 中添加一个断点并要求调试我的页面之前,一切似乎都正常工作(注释与否)。一旦我添加了一个断点,就会发生无限循环,并且我会被最大执行时间或最大内存限制所阻止。我用一个小文件 (20KB) 测试了它,它似乎可以工作,调试与否,还有一个更大的文件 (750KB),但它失败了。在步进时,我绝对可以看到我的密钥$k在第二次迭代后没有更新。

如果有人有任何想法,或者任何可以帮助我在没有无限循环的情况下进行调试的东西,那就太好了!

非常感谢您的时间和帮助!

Jer*_*ris 5

我刚刚在同一个文件中完成了一些类似的工作。我花了很长时间才意识到的一件事是,SimpleXML 扩展中存在一个可能导致此问题的错误:https ://bugs.php.net/bug.php?id =55098

似乎对我有用的是而不是做:

foreach ($colourScheme as $k => $xmlColour) {
   ...
}
Run Code Online (Sandbox Code Playgroud)

尝试使用以下children()方法:

foreach ($colourScheme->children() as $k => $xmlColour) {
   ...
}
Run Code Online (Sandbox Code Playgroud)

另一件要尝试的事情是在尝试循环之前用计数包装它:

if ($colourScheme->count() > 0) {
   ...
}
Run Code Online (Sandbox Code Playgroud)

这里的问题是 SimpleXML 对象不是数组,并且并不总是像您认为的那样表现。甚至 的文档children()(可能与foreach循环中发生的转换行为相同)也说无论是否有子元素都将返回 SimpleXML 元素。因此,您一遍又一遍地迭代同一个对象(无限循环):

在此处输入图片说明

如果所有其他方法都失败了,您可以将其转换为真正的数组并以这种方式处理:

$xml = simplexml_load_string($xmlstring);
$json = json_encode($xml);
$array = json_decode($json,TRUE);
Run Code Online (Sandbox Code Playgroud)

参考:

http://php.net/manual/en/simplexmlelement.children.php http://php.net/manual/en/simplexmlelement.count.php