我正在尝试解析50兆字节的.csv文件。文件本身很好,但我正试图解决所涉及的大量超时问题。每个都设置上传明智,我可以轻松上传并重新打开文件,但在浏览器超时后,我收到500内部错误。
我的猜测是我可以将文件保存到服务器上,打开它并保持我处理的行的会话值。在某一行之后,我通过刷新重置连接并在我离开的行处打开文件。这是一个可行的想法吗?以前的开发人员制作了一个非常低效的MySQL类,它控制着整个站点,所以如果我不需要,我不想写自己的类,而且我不想乱用他的类。
TL; DR版本:保存我当前使用的38K行产品的CSV文件的最后一行是否有效,并且在X行数后,重置连接从我离开的地方开始?或者是否有其他方法可以解析大型CSV文件而不会超时?
注意:这是PHP脚本执行时间。目前在38K行,通过命令行运行大约需要46分钟和5秒。当我从浏览器中删除它时,它可以100%正常工作,这表明它是浏览器超时。就谷歌告诉我而言,Chrome的超时时间不可编辑,而Firefox的超时工作很少。
答案 0 :(得分:2)
我建议从命令行运行php并将其设置为cron作业。这样您就不必修改代码了。没有超时问题,您可以轻松解析大型CSV文件。
还要检查此link
答案 1 :(得分:1)
由于拼写错误和语法,你的帖子有点不清楚,你能编辑吗?
如果您说上传本身没问题,但延迟是在处理文件,那么最简单的方法是使用多个线程并行解析文件。您可以使用java内置的Executor类或Quartz或Jetlang来执行此操作。
每个runnable都这样做:
答案 2 :(得分:1)
你可以这样做:
<?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);
可能会解决您的超时问题。