博客
关于我
php csv 导出
阅读量:793 次
发布时间:2023-02-27

本文共 2560 字,大约阅读时间需要 8 分钟。

PHP大数据导出实践总结

近年来,公司项目中经常需要处理大数据的导出需求。虽然之前开发过几次导出功能,但面对数据量较大的挑战时,发现了不少坑。现将这些经验总结如下:

1. PHP配置问题

在处理大数据导出时,PHP的环境配置需要特别注意:

  • 执行时间限制:默认情况下,PHP脚本执行时间限制为30秒。若数据量较大(如百万级别),30秒往往不够用。建议在脚本开头添加 set_time_limit(0),以避免因超时而中断。

  • 内存限制:PHP的默认内存限制为128M。虽然可以通过修改 memory_limit 来提升,但这在实际服务器环境中往往不太现实。建议谨慎使用,避免因内存过大占用而引发问题。

2. Excel文件限制

在选择Excel作为导出格式时,需注意以下限制:

  • 单表数据限制:Excel 2007-2010版本支持的单表最大数据量为1048576行,16384列。因此,若一次性导入一张表的数据超过该限制,会导致内存溢出。

  • PHPExcel内存问题:使用 fputcsv 导入大数据时,PHPExcel会将数据缓存到一个变量中,容易引发内存溢出。解决方案是通过分批导入和使用 PHPExcel_Settings::setCacheStorageMethod 更改缓冲方式。

3. CSV文件优化

虽然CSV文件格式在一定程度上克服了Excel的数据量限制,但仍需注意以下问题:

  • 输出缓存问题:使用 putcsv 函数进行大数据输出时,输出缓存可能过大,导致错误。需定期通过 ob_flush()flush() 刷新缓存。

  • 分割文件:由于CSV文件没有Excel的数据量限制,直接导入可能导致内存溢出。建议将数据分割成多个CSV文件,避免一次性处理过多数据。

4. 导出解决方案

针对大数据导出的具体场景,建议采取以下优化措施:

  • 分批处理数据:从数据库中分批读取数据,以防止变量内存溢出。

  • 选择合适的文件格式:采用CSV文件格式导出,既支持大数据量,又方便后续处理和查看。

  • 分割文件保存:为了避免Excel或其他工具读取时的数据量限制,建议将数据分割成多个CSV文件保存。

  • 文件压缩下载:为了提供更友好的用户体验,建议将多个CSV文件压缩成ZIP格式,方便用户下载并解压。

  • 5. 代码示例

    以下是一个实现大数据导出的PHP脚本示例:

    function putCsv(array $head, $data, $mark = 'attack_ip_info', $fileName = "test.csv")
    {
    set_time_limit(0);
    $sqlCount = $data->count();
    header('Content-Type: application/vnd.ms-excel;charset=utf-8');
    header('Content-Disposition: attachment;filename="' . $fileName . '"');
    header('Cache-Control: max-age=0');
    $sqlLimit = 100000;
    $limit = 100000;
    $cnt = 0;
    $fileNameArr = array();
    for ($i = 0; $i < ceil($sqlCount / $sqlLimit); $i++) {
    $fp = fopen($mark . '_' . $i . '.csv', 'w');
    fputcsv($fp, $head);
    $dataArr = $data->offset($i * $sqlLimit)->limit($sqlLimit)->get()->toArray();
    foreach ($dataArr as $a) {
    $cnt++;
    if ($limit == $cnt) {
    ob_flush();
    flush();
    $cnt = 0;
    }
    fputcsv($fp, $a);
    }
    fclose($fp);
    }
    $zip = new ZipArchive();
    $filename = $mark . ".zip";
    $zip->open($filename, ZipArchive::CREATE);
    foreach ($fileNameArr as $file) {
    $zip->addFile($file, basename($file));
    }
    $zip->close();
    foreach ($fileNameArr as $file) {
    unlink($file);
    }
    header("Cache-Control: max-age=0");
    header("Content-Description: File Transfer");
    header('Content-disposition: attachment; filename=' . basename($filename));
    header("Content-Type: application/zip");
    header("Content-Transfer-Encoding: binary");
    @readfile($filename);
    unlink($filename);
    }

    总结

    以上内容仍有优化空间,例如可以通过异常捕获机制处理临时文件删除问题,或通过生成多个工作表的方式优化文件格式。希望以上实践经验能为开发提供参考,欢迎随时交流心得!

    转载地址:http://ohvfk.baihongyu.com/

    你可能感兴趣的文章