当前位置: 首页 > 知识库问答 >
问题:

在foreach循环中使用array_combine时占用了PHP内存

南宫阳冰
2023-03-14

foreach循环中尝试使用array\u combine时遇到问题。它将以一个错误结束:

PHP Fatal error:  Allowed memory size of 268435456 bytes exhausted (tried to allocate 85 bytes) in

这是我的密码:

$data = array();
$csvData = $this->getData($file);
if ($columnNames) {
    $columns = array_shift($csvData);
    foreach ($csvData as $keyIndex => $rowData) {
        $data[$keyIndex] = array_combine($columns, array_values($rowData));
    }
}

return $data;

我使用的源文件CSV大约有1,000,000行。这一排

$csvData = $this->getData($file)

我使用while循环读取CSV并将其分配到一个数组中,它可以正常工作。故障来自array\u combineforeach循环。

你有什么想法来解决这个问题,或者只是有一个更好的解决方案?

下面是读取CSV文件的代码(使用而循环)

$data = array();
if (!file_exists($file)) {
    throw new Exception('File "' . $file . '" do not exists');
}

$fh = fopen($file, 'r');
while ($rowData = fgetcsv($fh, $this->_lineLength, $this->_delimiter, $this->_enclosure)) {
    $data[] = $rowData;
}
fclose($fh);
return $data;

如果您正在使用CSV文件,上面的代码可以正常工作

共有1个答案

薛烨霖
2023-03-14

实际上,您在内存中保留(或试图保留)整个数据集的两个不同副本。首先,使用getData()将整个CSV数据加载到内存中,然后通过在内存中的数据上循环并创建一个新数组,将数据复制到$data数组中。

加载CSV数据时,应使用基于流的读取,以便在内存中仅保留一个数据集。如果您使用的是PHP5.5(顺便说一句,您肯定应该这样做),那么将getData方法更改为如下所示即可:

protected function getData($file) {
    if (!file_exists($file)) {
        throw new Exception('File "' . $file . '" do not exists');
    }

    $fh = fopen($file, 'r');
    while ($rowData = fgetcsv($fh, $this->_lineLength, $this->_delimiter, $this->_enclosure)) {
        yield $rowData;
    }
    fclose($fh);
}

这使用了一个所谓的生成器,它是PHP

UPDATE解释现在如何提取列标题。

$data = array();
$csvData = $this->getData($file);
if ($columnNames) { // don't know what this one does exactly
    $columns = null;
    foreach ($csvData as $keyIndex => $rowData) {
        if ($keyIndex === 0) {
            $columns = $rowData;
        } else {
            $data[$keyIndex/* -1 if you need 0-index */] = array_combine(
                $columns, 
                array_values($rowData)
            );
        }
    }
}

return $data;
 类似资料:
  • 在循环中尝试使用时遇到问题。它将以一个错误结束: 这是我的密码: 我使用的源文件CSV大约有1,000,000行。这一排 我使用while循环读取CSV并将其分配到一个数组中,它可以正常工作。故障来自和循环。 你有什么想法来解决这个问题,或者只是有一个更好的解决方案? 下面是读取CSV文件的代码(使用而循环) 如果您正在使用CSV文件,上面的代码可以正常工作

  • 我使用的php foreach语句如下所示:

  • 问题内容: 在循环中使用/ 是否有任何问题?我试图遍历文件数组和每个文件的内容。 这段代码确实有效,但是这可能会出问题吗?我让某人告诉我,您不应该在这样的高阶函数中使用/ ,所以我只是想问一下这是否有问题。 问题答案: 确保代码确实有效,但是我很确定它不会执行您期望的功能。它只会触发多个异步调用,但此后函数会立即返回。 顺序阅读 如果要顺序读取文件, 则不能使用。只需使用现代循环即可,该循环将按预

  • 此select语句返回4k行。在我的应用程序中占用时间的是while循环。单循环就需要2到4分钟。关于如何优化它有什么想法吗? 不要太担心查询本身,因为它不会在查询响应上花费太多时间。

  • 问题内容: 我正在运行此数据库调用以获取多维数组,我试图获取每个数组的键,但是当我尝试将其显示为空白或数组时。 这是我的PHP循环遍历: 另外,当我运行一个仅将数组吐出的测试时,这就是结果,我想要呈现的是 [费城] 问题答案: 您可以这样访问数组键:

  • 问题内容: 我第一次不了解PHP。我一直在脚本中使用for循环,while循环,foreach循环。我想知道 哪一个性能更好? 选择循环的标准是什么? 当我们在另一个循环中循环时应该使用哪个? 我一直想知道要使用哪个循环的代码。 很明显,我可以使用while编写上面的代码。希望有人能帮助我找出哪个循环更适合使用。 问题答案: 哪一个性能更好? 没关系 选择循环的标准是什么? 如果只需要遍历对象或数