【问题标题】:Can you get a specific xml value without loading the full file?您可以在不加载完整文件的情况下获得特定的 xml 值吗?
【发布时间】:2011-01-10 10:40:51
【问题描述】:

我最近编写了一个 PHP 插件来连接我的 phpBB 安装,它将获取我用户的 Steam ID,将它们转换为 Steam 在其网站上使用的社区 ID,获取该社区 ID 的 xml 文件,获取avatarFull(包含完整头像的链接),通过 curl 下载,调整大小,并将其设置为用户的新头像。

实际上,它是将我的论坛头像与 Steam 的头像同步(Steam 是一个游戏社区/平台,我经营一个游戏部落)。我的问题是,每当我从 xml 文件中读取值时,每个用户都需要大约一秒钟的时间,因为它会在搜索变量之前加载整个 xml 文件,这会导致整个脚本需要很长时间才能完成。

理想情况下,我希望我的脚本每天运行几次,以检查 Steam 中的每个 avatarFull 值并检查它是否已更改(如果有,请下载文件),但目前我需要很长时间才能完成把所有东西都绑起来等着。

有没有办法让服务器只提供我正在寻找的 xml 值而不加载整个东西? 这是我当前调用该值的方式:

$xml = @simplexml_load_file("http://steamcommunity.com/profiles/".$steamid."?xml=1");
$avatarlink = $xml->avatarFull;

这是一个示例 xml 文件:XML file

【问题讨论】:

    标签: php xml load


    【解决方案1】:

    文件不大。解析它不需要太多时间。您的第二个主要浪费在网络通信上。

    由于没有办法解决这个问题,您必须实现缓存。安排一个脚本,每隔一小时左右在您的服务器上运行一次,寻找更改。这个脚本会花费很多时间——每个用户至少需要一秒钟;如果必须下载图片,则需要几秒钟。

    当它有最新的图片时,它会将它存储在您服务器上的某个预定义位置。为您的网页提供服务的脚本将使用此位置,而不是与 Steam 通信。这样它们将立即生效,并且图片最多会过期 1 小时。

    补充:这里有一个补充的想法:让您的访问者向 Steam 执行 AJAX 请求,并通过 JavaScript 检查图片是否已更改。仅对他们实际查看的图片执行此操作。如果有,那么您可以立即在他们的浏览器中替换过时的图片。您也可以通知您的服务器,然后谁可以立即下载更新的图片。也许您甚至不需要自己安排任何事情。

    【讨论】:

    • 我想过这个问题,但是由于每天有数千次浏览量,而且用户头像发生变化的可能性很小,因此等待一切运行的时间可能会比以前多得多。另外,考虑到您的解决方案,在该页面上使用新图片可能是不明智的,因为检查所有图片、下载新图片、然后替换当前图片会导致图像刷新时间晚得多。需要。
    【解决方案2】:

    您必须读取整个流以获取所需的数据,但不必将其保存在内存中。

    如果我使用 Java 执行此操作,我会使用 SAX 解析器而不是 DOM 解析器。我可以处理我感兴趣的几个值,而不是在内存中保留一个大的 DOM。看看 PHP 是否有适合你的东西。

    【讨论】:

      【解决方案3】:

      SimpleXml 是一个 DOM 解析器。它会在您使用它之前将整个文档加载并解析到内存中。如果您不希望这样,请使用 XMLReader,它允许您在从流中读取 XML 时对其进行处理,例如获取头像后,您可以退出处理。

      但是就像其他人已经在此页面上的其他地方指出的那样,对于一个如图所示的小文件,这很可能是网络延迟问题而不是 XML 问题。

      另见Best XML Parser for PHP

      【讨论】:

        【解决方案4】:

        该文件看起来足够小。解析应该不需要那么长时间。由于某种网络问题和解析速度慢,它可能需要很长时间。

        如果网络是您的问题,那么再多的诡计也无济于事:(。

        如果不是网络,那么您可以尝试对输入进行正则表达式匹配。那可能会稍微快一些。

        试试这个表达式:

        /<avatarFull><![CDATA[(.*?)]]><\/avatarFull>/
        

        并阅读第一场小组赛的链接。

        您可以尝试 SAX 解析方式 (http://php.net/manual/en/book.xml.php) 但正如我所说,由于文件很小,我怀疑它是否真的会有所作为。

        【讨论】:

        • 我可能只使用strpos,它的速度尽可能快。尽管这些解决方案中的任何一个都会破坏 XML 格式的微小变化。
        • 这也应该可以。无论如何,在这种情况下,我并不期望 regexp 和 strpos 之间有任何有趣的速度差异:)。
        【解决方案5】:

        您可以利用缓存 simplexml_load_file() 的结果,例如 memcached 或文件系统。这是典型的工作流程:

        • 检查是否在最后 N 秒内处理了 XML 文件
        • 成功返回处理结果
        • 从 simplexml 获取结果失败时
        • 处理它们
        • 调整图片大小
        • 将结果存储在缓存中

        【讨论】:

          猜你喜欢
          • 2019-04-03
          • 1970-01-01
          • 2020-12-08
          • 2013-02-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-02-25
          • 2010-09-23
          相关资源
          最近更新 更多