概述:

之前写过一篇文章叫PHP百万级数据导出方案(多csv文件压缩),发现很多朋友都很感兴趣,但是当时用的方法比较不方便,可能不太符合很多人的需求。后来想了一下如何优化时,了解到能用生成器来处理内存溢出更方便,所以当时文章中也补充分享了一下这想法。然而,发现更多朋友对如何结合生成器导出数据感兴趣,因此这篇文章,我来填下坑。

准备:

1、了解生成器yield

我上篇文章PHP百万级数据导出方案(多csv文件压缩) 说了几个坑,大家可以先去回顾一下。然后我们可以看一下前辈的对生成器介绍的文章: PHP性能优化利器:生成器 yield理解,来理解一下生成器防止内存溢出的原理。

2、解决数据查询内存溢出

了解完生成器yield原理之后,我们还需要解决一个问题,我们常用的mysql查询函数是mysqli_query(connection,query,resultmode);,通常都是直接填写第一第二个参数就直接查询,但该函数默认的是对全部结果集进行缓存,这会导致数据过多的时候,内存也会溢出。因此,我们需要设置第三个参数为MYSQLI_USE_RESULT来逐行读取结果集。那或许您有疑问为什么不直接 遍历该mysqli_query()方法返回的结果来当每一行数据写到CSV中,而还要用yield来存储一次每行数据再写到CSV中呢?其实这是因为mysqli_query()返回的结果是mysqli_result Object形式,而fputcsv()这个方法要求第二个参数为数组。所以yield的作用就是中转站,但是他是一行行运输数据,而不是读多行来运输数据。

代码:<?php

/*

* 该方法是把数据库读出的数据进行CSV文件输出,能接受百万级别的数据输出,因为用生成器,不用担心内存溢出。

* @param string $sql 需要导出的数据SQL

* @param string $mark 生成文件的名字前缀

*

*/

function putCsv($sql, $mark)

{

set_time_limit(0);

header('Content-Type: application/vnd.ms-excel;charset=utf-8');

header('Content-Disposition: attachment;filename="' . $mark . '"');

header('Cache-Control: max-age=0');

$file_num = 0;  //文件名计数器

$fileNameArr = array();

$fp = fopen($mark .'_'.$file_num .'.csv', 'w'); //生成临时文件

$fileNameArr[] = $mark .'_'.$file_num .'.csv';

fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF));//转码,防止乱码

foreach (query($sql) as $a) {

fputcsv($fp, $a);

}

fclose($fp);  //每生成一个文件关闭

}

//生成器来缓存mysql查询结果,返回类型为数组

function query($sql){

$con = mysqli_connect("localhost", "root", "root");

if (!$con) {

die('Could not connect: ' . mysqli_error());

}

mysqli_select_db($con, "dbmigs_smz");

mysqli_query($con,'set names utf8');

$n = 0;

//    print_r(mysqli_query($con, $sql,MYSQLI_USE_RESULT) ); mysqli_result Object 返回

//该处用MYSQLI_USE_RESULT 就是不缓存结果集中,也是为了避免内存溢出,相当于mysql_unbuffered_query

foreach (mysqli_query($con, $sql,MYSQLI_USE_RESULT) as $row ){  //

yield $row;

echo $n++  . "
";  //输出行数

}

$con->close();

}

//$sql = 'SELECT id,ArticleClassify,ArticleTitle FROM `test_yield`  where id

$sql = 'SELECT id,ArticleClassify,ArticleTitle FROM `test_yield`  where id

$mark = 'test';

putCsv($sql,$mark,1,2);

?>

php直接导出csv,PHP百万级数据导出方案(生成器直接输出单个CSV)相关推荐

  1. PHP如何实现百万级数据导出

    公司目前有一个需求,需要对一个日增量在20万+数据量的数据表中的数据进行可自定义条件筛选的导出数据,该功能需要对多个部门进行开发使用,要保证功能可用的前提下,尽量优化体验. 首先介绍一下当前可利用的资 ...

  2. java excel 使用ExcelWriter 百万级数据导出

    一.Java 通过hutool工具类ExcelWriter 导出 运用到多线程分页查询 这个采用的是Java的utool工具类ExcelWriter 导出 踩过一些坑,尽量用一条sql 将所有数据查询 ...

  3. 阿里开源百万级数据导出Excel表格 三步简单导出 附官方文档

    阿里巴巴Excel导出优化速度 ,64M内存20秒读取75M(46W行25列)的Excel(3.0.2+版本) 官方文档:EasyExcel · 语雀EasyExcel是一个基于Java的简单.省内存 ...

  4. Java 亿万级数据导出到Excel

    由于项目需要,处理百万级数据导出问题. 直接开始撸代码~ 导入依赖 <!-- 文件导出--><dependency><groupId>org.apache.poi& ...

  5. php 快速导出百万级数据到 csv 或者 excel 文件

    目录 一.导出思路 二.导出源码 三.蠕虫复制 一.导出思路 需要考虑服务器内存 需要考虑程序运行的最大时间 缺少 BOM 头导致乱码的处理 如果导出数量过大,推荐使用循环导出,每次循环这里以导出一万 ...

  6. springboot+poi导出百万级数据避免OOM内存溢出

    springboot+poi导出百万级数据避免OOM内存溢出 文章目录 springboot+poi导出百万级数据避免OOM内存溢出 前言 一.具体实现 二.代码实现 1.引入poi包 2.功能代码 ...

  7. easyexcel导出百万级数据_百万级数据下的mysql深度解析

    点击蓝字关注我们!每天获取最新的编程小知识! 源 / php中文网      源 / www.php.cn mysql 作为一款非常优秀的免费数据库被广泛的使用,平时我们开发的项目数据过百万的时候不多 ...

  8. 百万级数据的导出解决方案

    一.传统POI的的版本优缺点比较 首先我们知道POI中我们最熟悉的莫过于WorkBook这样一个接口,我们的POI版本也在更新的同时对这个几口的实现类做了更新: HSSFWorkbook : 这个实现 ...

  9. phython在file同时写入两个_轻松支撑百万级数据点写入 京东智联云时序数据库HoraeDB架构解密...

    本文将通过对时序数据的基本概念.应用场景以及京东智联云时序数据库HoraeDB的介绍,为大家揭秘HoraeDB的核心技术架构和解决方案. 首先我们来了解下时序数据库的基本概念.时序数据库全称时间序列数 ...

最新文章

  1. 皮一皮:当有人在我身边时...
  2. 丘成桐在CNCC会议的演讲全文
  3. 心疼吗?被指是“傻X” 罗永浩深夜怒怼网友
  4. CleanCodeHandbook Chapter 3: Linked List(20-24)
  5. InflateException:Bin file line #19:Error inflating class MyTextView
  6. Android开源代码解读のOnScrollListener实现ListView滚屏时不加载数据
  7. 数字电子技术基础阎石(第六版)基本公式和若干常用公式的电路证明方法
  8. 最简单的黑客帝国代码雨教程C++
  9. Access操作必须使用一个可更新的查询
  10. html导航栏分割线如何,网页导航栏用图片做的分割线,第一个分割线怎么取消...
  11. python 解压文件 重名_Python批量重命名压缩文件
  12. 用Python搞出自己的云词图 | 【带你装起来】
  13. 2. 样式,大纲和目录
  14. android usb联接网络打印机,打印到USB或预先选择的网络打印机从嵌入式android
  15. 计算机组成原理组间串行进位,计算机组成原理第二章课件.ppt
  16. 重新安装anaconda的感想
  17. 一个月薪12000的北京程序员的真实生活
  18. 数商云跨境电商平台运营总结:整合渠道+深引流量
  19. 数采仪 环保标准 数据采集传输仪
  20. 理解和使用Promise.all和Promise.race

热门文章

  1. 大数据实验报告总结体会_建设大数据中台架构思考与总结
  2. android应用程序的组件,Android基础之应用程序组件
  3. 前端字符串内HTML标签无效的处理方式
  4. Linux多线程编程实例解析
  5. [bash] 打包某目录(可以是绝对路径)下的指定扩展名的文件
  6. fatal error C1083: 无法打开包括文件:dxtrans.h: No such file or directory
  7. 动态样式计算 动态样计算 <span :style=“{‘left‘:`${(l+1)*16 - 6}`+‘px‘}“></span>
  8. [react] 为什么属性使用className而不是class呢?
  9. [react] 使用React的memo和forwardRef包装的组件为什么提示children类型不对?
  10. 前端学习(3343):ant design中导航使用