php直接导出csv,PHP百万级数据导出方案(生成器直接输出单个CSV)
概述:
之前写过一篇文章叫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)相关推荐
- PHP如何实现百万级数据导出
公司目前有一个需求,需要对一个日增量在20万+数据量的数据表中的数据进行可自定义条件筛选的导出数据,该功能需要对多个部门进行开发使用,要保证功能可用的前提下,尽量优化体验. 首先介绍一下当前可利用的资 ...
- java excel 使用ExcelWriter 百万级数据导出
一.Java 通过hutool工具类ExcelWriter 导出 运用到多线程分页查询 这个采用的是Java的utool工具类ExcelWriter 导出 踩过一些坑,尽量用一条sql 将所有数据查询 ...
- 阿里开源百万级数据导出Excel表格 三步简单导出 附官方文档
阿里巴巴Excel导出优化速度 ,64M内存20秒读取75M(46W行25列)的Excel(3.0.2+版本) 官方文档:EasyExcel · 语雀EasyExcel是一个基于Java的简单.省内存 ...
- Java 亿万级数据导出到Excel
由于项目需要,处理百万级数据导出问题. 直接开始撸代码~ 导入依赖 <!-- 文件导出--><dependency><groupId>org.apache.poi& ...
- php 快速导出百万级数据到 csv 或者 excel 文件
目录 一.导出思路 二.导出源码 三.蠕虫复制 一.导出思路 需要考虑服务器内存 需要考虑程序运行的最大时间 缺少 BOM 头导致乱码的处理 如果导出数量过大,推荐使用循环导出,每次循环这里以导出一万 ...
- springboot+poi导出百万级数据避免OOM内存溢出
springboot+poi导出百万级数据避免OOM内存溢出 文章目录 springboot+poi导出百万级数据避免OOM内存溢出 前言 一.具体实现 二.代码实现 1.引入poi包 2.功能代码 ...
- easyexcel导出百万级数据_百万级数据下的mysql深度解析
点击蓝字关注我们!每天获取最新的编程小知识! 源 / php中文网 源 / www.php.cn mysql 作为一款非常优秀的免费数据库被广泛的使用,平时我们开发的项目数据过百万的时候不多 ...
- 百万级数据的导出解决方案
一.传统POI的的版本优缺点比较 首先我们知道POI中我们最熟悉的莫过于WorkBook这样一个接口,我们的POI版本也在更新的同时对这个几口的实现类做了更新: HSSFWorkbook : 这个实现 ...
- phython在file同时写入两个_轻松支撑百万级数据点写入 京东智联云时序数据库HoraeDB架构解密...
本文将通过对时序数据的基本概念.应用场景以及京东智联云时序数据库HoraeDB的介绍,为大家揭秘HoraeDB的核心技术架构和解决方案. 首先我们来了解下时序数据库的基本概念.时序数据库全称时间序列数 ...
最新文章
- 皮一皮:当有人在我身边时...
- 丘成桐在CNCC会议的演讲全文
- 心疼吗?被指是“傻X” 罗永浩深夜怒怼网友
- CleanCodeHandbook Chapter 3: Linked List(20-24)
- InflateException:Bin file line #19:Error inflating class MyTextView
- Android开源代码解读のOnScrollListener实现ListView滚屏时不加载数据
- 数字电子技术基础阎石(第六版)基本公式和若干常用公式的电路证明方法
- 最简单的黑客帝国代码雨教程C++
- Access操作必须使用一个可更新的查询
- html导航栏分割线如何,网页导航栏用图片做的分割线,第一个分割线怎么取消...
- python 解压文件 重名_Python批量重命名压缩文件
- 用Python搞出自己的云词图 | 【带你装起来】
- 2. 样式,大纲和目录
- android usb联接网络打印机,打印到USB或预先选择的网络打印机从嵌入式android
- 计算机组成原理组间串行进位,计算机组成原理第二章课件.ppt
- 重新安装anaconda的感想
- 一个月薪12000的北京程序员的真实生活
- 数商云跨境电商平台运营总结:整合渠道+深引流量
- 数采仪 环保标准 数据采集传输仪
- 理解和使用Promise.all和Promise.race
热门文章
- 大数据实验报告总结体会_建设大数据中台架构思考与总结
- android应用程序的组件,Android基础之应用程序组件
- 前端字符串内HTML标签无效的处理方式
- Linux多线程编程实例解析
- [bash] 打包某目录(可以是绝对路径)下的指定扩展名的文件
- fatal error C1083: 无法打开包括文件:dxtrans.h: No such file or directory
- 动态样式计算 动态样计算 <span :style=“{‘left‘:`${(l+1)*16 - 6}`+‘px‘}“></span>
- [react] 为什么属性使用className而不是class呢?
- [react] 使用React的memo和forwardRef包装的组件为什么提示children类型不对?
- 前端学习(3343):ant design中导航使用