【问题标题】:PHP foreach while handling chunks处理块时的PHP foreach
【发布时间】:2015-09-19 13:29:47
【问题描述】:

我目前正在尝试处理一个大型 XML 文件 (1,5 gb), 目前它正在分块打开

    $handle = fopen($url, "r") or die("Couldn't get handle");
        if ($handle) {
            while (!feof($handle)) {
            $chunk = fgets($handle, 4096);
            // echo each chunk
            echo $chunk;
        }
    fclose($handle);
    }

我不想回显这个块,而是保存每一行,直到找到</file>。为此:

$handle = fopen($url, "r") or die("Couldn't get handle");
if ($handle) {
    while (!feof($handle)) {
        $chunk = fgets($handle, 4096);
        // echo '<xmp>'.$buffer.'</xmp>';
            if (strpos($fullstring,'</file>') !== false) {
                // i should have everything between <file> and </file>

                // empty the $fullstring so it can fill with chunks again
                $fullstring = '';
            } else {
                $fullstring .= $chunk;
            }

    }
    fclose($handle);
}

现在我想在 foreach 循环中运行它。但不是循环每个找到的,而是循环相同的&lt;file&gt;&lt;/file&gt; 用于所有找到的&lt;file&gt;&lt;/file&gt;

如何处理在分块加载文件时找到的每个&lt;file&gt;content&lt;/file&gt;

提前谢谢你!

【问题讨论】:

    标签: php xml buffer


    【解决方案1】:

    如果您需要解析大型 XML 文件,我建议将 XMLReader 与 DOM 结合使用。使用 XMLReader 获取块元素节点,将其展开为 DOM 并使用 Xpath 从块中获取详细信息。

    $reader = new XMLReader;
    $reader->open($file);
    $dom = new DOMDocument;
    $xpath = new DOMXpath($dom);
    
    // look for the first chunk
    while ($reader->read() && $reader->localName !== 'file') {
      continue;
    }
    
    // while you have an file element
    while ($reader->localName === 'file') {
      $node = $reader->expand($dom);
    
      // $xpath->evaluate('expression', $node);
      // ...
    
      // move to the next chunk (next file sibling node)
      $reader->next('file');
    }
    

    【讨论】:

    • 我应该在 'while (!feof($handle)) {' 中运行这段代码?
    • 不,这是一种不同的方法。它取代了你的来源。 XMLReader::open() 打开文件并将逐个节点读取它。只有XMLReader:expand() 会将该节点及其后代读入内存。
    • 我对 DOM 和 XMLReader 都不熟悉。回显在“文件”中找到的元素的适当方法是什么?感谢您迄今为止的帮助!
    • 使用 Xpath:$xpath-&gt;evaluate('string(nodename)')。 Xpath 是一种从 DOM 中获取节点和值的表达式语言。 echo $dom-&gt;saveXml($node); 将输出节点的(外部)XML。
    • echo $dom->saveXml($node);没有显示任何内容,错误日志也没有。
    【解决方案2】:

    我会推荐 PHP 的 DomDocument 方法。它对于解析您可能使用文件句柄或file_get_contents 等获得的 XML 或 HTML 文档很有用。

    http://php.net/manual/en/class.domdocument.php

    另外,PHP 具有array_chunk 功能http://php.net/manual/en/function.array-chunk.php

    【讨论】:

    • 主 XML 文件为 1.5 GB,几乎不可能使用 file_get_contents,因此分块 :)
    • 好的,明白了。不过,要进行任何解析,我认为文件需要读入(通常是字符串表示)
    • 我不太了解你的遮阳篷,你能详细说明一下吗?
    • 基本上,即使文件很大,要进行任何解析(解析成可以使用的元素),您都需要将文件读入变量中。
    猜你喜欢
    • 2014-04-16
    • 2014-05-14
    • 2021-09-23
    • 2023-03-06
    • 2017-01-24
    • 1970-01-01
    • 2018-05-21
    • 2014-10-01
    • 1970-01-01
    相关资源
    最近更新 更多