3

我正在尝试解析一个 50 兆字节的 .csv 文件。该文件本身很好,但我试图解决所涉及的大量超时问题。每个都设置为上传明智,我可以轻松上传并重新打开文件,但在浏览器超时后,我收到 500 内部错误。

我的猜测是我可以将文件保存到服务器上,打开它并保留我处理的行的会话值。在某一行之后,我通过刷新重置连接并在我离开的那一行打开文件。这是一个可行的想法吗?之前的开发者做了一个效率很低的 MySQL 类,它控制着整个网站,所以我不想写自己的类,如果我没有必要,我也不想乱他的类。

TL;DR 版本:保存我当前在具有 38K 行产品的 CSV 文件中的最后一行,然后在 X 行之后,重置连接并从我离开的地方开始是否有效?还是有另一种方法来解析大型 CSV 文件而不会超时?

注意:这是 PHP 脚本执行时间。目前在 38K 行,通过命令行运行大约需要 46 分 5 秒。当我从浏览器中删除它时,它 100% 正常工作,这表明它是浏览器超时。据谷歌告诉我,Chrome 的超时是不可编辑的,而 Firefox 的超时很少起作用。

4

3 回答 3

3

你可以这样做:

<?php

namespace database;

class importcsv
{
    private $crud;

    public function __construct($dbh, $table)
    {
        $this->crud = new \database\crud($dbh, $table);
        return $this;
    }

    public function import($columnNames, $csv, $seperator)
    {
        $lines = explode("\n", $csv);

        foreach($lines as $line)
        {
            \set_time_limit(30);
            $line = explode($seperator, $line);

            $data = new \stdClass();

            foreach($line as $i => $item) 
            {
                if(isset($columnNames[$i])&&!empty($columnNames[$i]))
                    $data->$columnNames[$i] = $item;
            }

            @$x++;

            $this->crud->create($data);
        }

        return $x;
    }

    public function importFile($columnNames, $csvPath, $seperator)
    {
        if(file_exists($csvPath))
        {
            $content = file_get_contents($csvPath);
            return $this->import($columnNames, $content, $seperator);
        }
        else
        {
            // Error
        }
    }
}

TL;DR:\set_time_limit(30);每次循环一行都可能会解决您的超时问题。

于 2012-08-03T17:07:08.923 回答
2

我建议从命令行运行 php 并将其设置为 cron 作业。这样您就不必修改代码。不会有超时问题,您可以轻松解析大型 CSV 文件。

还要检查这个链接

于 2012-08-03T17:19:22.760 回答
1

由于拼写错误和语法,您的帖子有点不清楚,您能编辑一下吗?

如果你说 Upload 本身没问题,但延迟在处理文件,那么最简单的做法是使用多个线程并行解析文件。您可以使用 java 内置的 Executor 类,或者 Quartz 或 Jetlang 来执行此操作。

  • 查找文件的大小或行数。
  • 选择一个线程负载(假设每个线程 1000 行)
  • 启动执行器
  • 循环读取文件。
  • 对于每 1000 行,创建一个 Runnable 并将其加载到 Executor
  • 启动执行器
  • 等到所有线程完成

每个可运行文件都这样做:

  1. 获取连接
  2. 插入 1000 行
  3. 记录结果
  4. 关闭连接
于 2012-08-03T17:06:33.553 回答