【问题标题】:Endless loading huge php file with high memory_limit无休止地加载具有高 memory_limit 的巨大 php 文件
【发布时间】:2012-11-09 11:51:39
【问题描述】:

简介

目前我正在处理 XML 文件。使用 PHP,我结合了几个 XML 文件。这是一个超出 PHP 默认 memory_limit 的大操作。

当我使用ini_set('memory_limit', '1024M'); 扩展限制时,致命错误消失了,脚本不再超过限制。

我现在遇到的问题是,在组合 XML 文件后,我的脚本有问题。 浏览器加载无穷无尽,我仍然能够在服务器端做所有事情。就像我自己发电子邮件一样,向数据库中添加行。但是所有客户端都不起作用。就像一个简单的echo 'Hello World';header('location: http://www.google.com');

在合并文件时,我记录了这些步骤。

$stores = $this->Store->getAll();
$this->log(2, 'all', 1337, 'Start processing ' . count($stores) . ' stores ';
foreach($stores as $store)
{
    $this->log(2, $store->id, 1337, 'Start processing store ';
    $this->process_store($store->id, false);
}
$this->log(2, 'all', 1337, 'Done with processing ' . count($stores) . ' stores ';
header('location: ' . BASE_URL . '/datatest');
die();

奇怪的是我的脚本确实记录了最后一个日志Done with processing。我在服务器端所做的任何事情都有效。

但标题(重定向)却没有。我的浏览器正在无限加载。

问题

  • 出了什么问题?
  • 浏览器是否会在一段时间后禁用与服务器的通信?

【问题讨论】:

  • @Chris Technical 我的脚本不会执行 die()exit()

标签: php memory-limit


【解决方案1】:

您可以通过使用 simpleXML 进行递归 XML 合并来规避内存问题

代码

<?php
private function mergeXML(&$base, $add)
{
    $new = $base->addChild($add->getName());
    foreach ($add->attributes() as $a => $b) {
        $new[$a] = $b;
    }
    foreach ($add->children() as $child) {
        $this->mergeXML($new, $child);
    }
}?>

用法

<?php mergeXML($xmlElement, simplexml_load_string($toMerge)) ?>

因此,您将开始并将 XML 1 与 XML2 合并到 TempXML1,然后将 TempXML1 与 XML3 合并,等等。这样,您只需在 xml 文件列表中查找,而无需将它们全部加载到内存中。

【讨论】:

  • XML 合并/组合工作正常。文件没问题。循环后保存到数据库工作。甚至给自己发电子邮件也能在循环之后工作。但在客户端,浏览器一直在加载。没有别的了:(
  • 好吧,如果是这样,也许客户端正在请求多个合并,这会占用内存。你应该检查一下。
  • 我不知道你到底是什么意思。在日志中我还保存了memory_get_peak_usage(true)/1024,最后一个日志告诉我102656
【解决方案2】:

你确定 BASE_URL . '/datatest' 是正确的 URL? 您还应该在 Location 上加上大写 L 以确保重定向正常工作。

在不进行整个合并的情况下尝试此操作,以首先验证您的标头重定向是否有效。

【讨论】:

  • 我完全确定标题有效。用的多了。我的浏览器只是无限加载...
  • 您能否尝试使用您的确切行但不进行合并并确保您被重定向?正如我所说,你应该有 Location 而不是 location 才能工作
  • 我试过了,位置和位置都有效。 (在实际代码中我使用$this-&gt;redirect();
  • 好的。只是想确定一下。您确定您的脚本没有打印任何内容吗?没有错误/警告显示阻止标题工作?检查你的错误日志。您可以使用 ob_start()/ob_end_clean() 来确保不打印任何内容并检查它是否有任何变化?
  • 这很奇怪......你的脚本在标题之前运行了多长时间?您可以尝试暂时“休眠”,然后重定向并检查它在这种情况下是否有效。如果它有效,那么您的合并方式存在问题,这是您没有看到的。如果没有,标题中的问题在很长一段时间后无法正常工作。
【解决方案3】:

我注意到服务器和客户端彼此断开连接。

终于找到了解决办法,真的很丑!

我必须在 foreach 循环内设置一个sleep(1); 以保持服务器和客户端的连接。

天哪,这比以前慢了:'(

【讨论】:

  • 嗯,最小工作 usleep(30000); 所以快 3 倍 :) 谢谢 @EricCope
猜你喜欢
  • 1970-01-01
  • 2018-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 2016-08-20
  • 2014-04-13
  • 1970-01-01
相关资源
最近更新 更多