PHP导出CSV需用fputcsv流式处理并加UTF-8 BOM:清空缓冲、设置header、写BOM、逐行fetch,避免内存溢出与Excel乱码。
最常用场景:后台导出报表,用户点击即下载。关键不是“保存到服务器”,而是让浏览器弹出下载对话框。
核心要点:fputcsv() 是 PHP 原生安全写 CSV 的函数,别用字符串拼接;输出前必须清空缓冲区、设置正确 header;MySQL 查询结果需转为二维数组(每行是 array)。
header() 之前没有输出(包括空格、BOM、echo、var_dump)ob_end_clean() 清除可能存在的前置输出rawurlencode() 处理,否则 IE/Edge 可能乱码fputcsv() 自动处理字段内含逗号、换行、双引号的情况,比手动 str_replace 可靠得多header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename="user_export_' . rawurlencode(date('Y-m-d')) . '.csv"');
header('Cache-Control: no-cache');
$output = fopen('php://output', 'w');
fputcsv($output, ['ID', '用户名', '邮箱', '注册时间']); // 表头
$stmt = $pdo->query("SELECT id, username, email, created_at FROM users WHERE status = 1");
while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
fputcsv($output, $row);
}
fclose($output);
用 fetchAll() 把全部数据读进内存,PHP 很容易报 Fatal error: Allowed memory size exhausted。必须流式处理(streaming)。
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false)
fetch() 逐行取,而不是 fetchAll()
ob_flush() + flush(),防止 Web 服务器缓冲卡住$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
$stmt = $pdo->prepare("SELECT id, username, DATE_FORMAT(created_at, '%Y-%m-%d') as date_str FROM users");
$stmt->execute();
$output = fopen('php://output', 'w');
fputcsv($output, ['ID', '用户名', '日期']);
$i = 0;
while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
fputcsv($output, $row);
$i++;
if ($i % 1000 === 0) {
ob_flush();
flush();
}
}
fclose($output);
根本原因:Excel for Windows 默认用 ANSI(GBK/GB2312)打开 CSV,而 PHP 输出的是 UTF-8。不加 BOM,Excel 就认不出来。
UTF-8 编码的 CSV 加 BOM,且必须加在文件最开头(fopen('php://output') 后立即写)\xEF\xBB\xBF,不能用 mb_convert_encoding 或其他方式生成Content-Type 仍写 charset=utf-8,不要改成 gbk
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename="data.csv"');
$output = fopen('php://output', 'w');
fwrite($output, "\xEF\xBB\xBF"); // 写入 UTF-8 BOM
fputcsv($output, ['姓名', '地址', '备注']);
fputcsv($output, ['张三', '北京市朝阳区', '测试用户']);
fclose($output);
适合需要审计日志、定时批量导出、或文件要复用的场景。重点是路径权限、文件命名防覆盖、以及下载链接的安全控制。
./uploads/),建议放 /var/tmp/ 或项目外独立目录uniqid() . '_' . date('Ymd_His'),避免并发写入冲突download.php?file=xxx.csv)做校验$_GET['file'] 是否为合法格式(正则匹配 ^[a-z0-9_]+\.csv$),并用 basename() 防止路径遍历保存示例(不输出,只写磁盘):
$filename = '/var/tmp/export_' . uniqid() . '_' . date('Ymd_His') . '.csv';
$output = fopen($filename, 'w');
fputcsv($output, ['ID', 'Name']);
fputcsv($output, [1, '测试']);
fclose($output);
// 记录到数据库或日志:成功写入 $filename
实际用的时候,BOM 和流式处理这两点最容易被跳过,一
出问题就花半天排查。尤其是导出功能上线后数据量变大,原来小表没问题的代码突然挂掉——大概率是没关缓冲查询或没分批 flush。
# mysql
# php
# excel
# windows
# 编码
# 浏览器
# edge
# 字节
# 中文乱码
# csv
# ai
# win
# sql
# echo
# Array
# for
# date
# fopen
# Error
# pdo
# 字符串
# 循环
# var
# 并发
# bom
# 下载链接
# 流式
# 清空
# 的是
# 注册时间
# 朝阳区
# 放在
# 尤其是
# 遍历
# 很容易
相关栏目:
【
Google疑问12 】
【
Facebook疑问10 】
【
网络优化76771 】
【
技术知识130152 】
【
IDC云计算60162 】
【
营销推广131313 】
【
AI优化88182 】
【
百度推广37138 】
【
网站推荐60173 】
【
精选阅读31334 】
相关推荐:
php485读数据时阻塞怎么办_php485非阻塞读取设置技巧【详解】
Win11屏幕亮度突然变暗怎么解决_自动变暗问题处理
Windows 11登录时提示“用户配置文件服务登录失败”怎么办_Windows 11修复损坏的用户配置文件
如何在 PHP 中按相同键合并两个关联数组为二维数组
Win11怎么设置开机自动连接宽带_Windows11创建拨号连接计划任务
如何在 Go 中可靠地测试含 time.Time 字段的结构体
Win11怎么关闭系统声音_Win11系统提示音静音设置【详解】
php能控制zigbee模块吗_php通过串口与cc2530 zigbee通信【介绍】
Win10怎么更改用户名 Win10修改账户名称操作教程
Win11怎么设置开机问候语_自定义Win11锁屏提示信息【技巧】
MAC如何启用访达侧边栏显示_MAC Finder偏好设置与常用目录添加【教程】
Win11怎么修复系统文件_使用sfc命令修复Win11系统【技巧】
php485在macos下怎么配置_php485 macOS系统配置指南【解答】
如何用正则与预处理高效拦截带干扰符的恶意域名
如何在 Python 测试中动态配置 @backoff 装饰器的重试次数
Win10怎样卸载DockerDesktop_Win10卸载DockerDesktop步骤【步骤】
如何使用Golang编写单元测试_创建Test函数验证业务逻辑
Win11应用商店下载慢怎么办 Win11更改DNS提速下载【修复】
php打包exe后无法写入文件_权限问题解决方法【教程】
mac怎么打开终端_MAC终端Terminal使用入门与常用命令【教程】
Windows怎样拦截QQ浏览器广告_Windows拦截QQ浏览器广告方法【方法】
Windows蓝屏错误0x0000001E怎么修复_KMODEEXCEPTIONNOTHANDLED排查
Win11怎么开启游戏工具栏_Windows11 Xbox Game Bar快捷键
Win11怎么设置虚拟内存最佳大小_Windows11性能选项自定义分页文件
c++中的Tag Dispatching是什么_c++利用标签分发优化函数重载【元编程】
Win11怎么设置默认PDF阅读器 Win11修改PDF打开方式【步骤】
Windows 10怎么隐藏特定更新补丁_Windows 10使用微软官方工具wushowhide.diagcab
php订单日志怎么导出excel_php导出订单日志到表格教程【教程】
php订单日志怎么按金额排序_php按订单金额排序日志方法【方法】
如何诊断并终止卡死的 multiprocessing 子进程
Win11资源管理器卡顿怎么办 Win11文件资源管理器重启技巧【优化】
Win11任务栏怎么固定应用 Win11将软件图标固定到底部【步骤】
Windows 11怎么设置默认解压软件_Windows 11为ZIP/RAR文件指定默认打开程序
Windows10蓝屏代码DPC_WATCHDOG_VIOLATION_Win10死机修复指南
Win11怎么开启游戏模式_Windows11优化游戏帧数设置指南
Win11怎么压缩文件 Win11自带压缩解压功能使用【教程】
Windows10电脑怎么连接蓝牙设备_Win10蓝牙配对失败解决方法
Windows电脑如何截屏?(四种快捷方法)
Win11此电脑不在桌面上_Windows 11桌面图标设置找回【步骤】
Win11怎么更改管理员名字 Win11修改账户名称详细步骤【教程】
php查询数据怎么导出csv_查询结果转csv文件保存【操作】
Windows10如何更改桌面背景_Win10个性化幻灯片放映设置
如何使用Golang匿名函数_快速定义临时函数逻辑
Python数据挖掘进阶教程_分类回归与聚类案例解析
ACF 教程:如何正确更新嵌套在多层 Group 字段内的子字段
Python邮件系统自动化教程_批量发送解析与模板应用
Win10怎样安装PPT模板_Win10安装PPT模板教程【步骤】
XML的“混合内容”是什么 怎么用DTD或XSD定义
c++中的可变参数模板(variadic templates)怎么用_c++模板编程黑魔法【C++11】
Win10系统怎么查看网络连接状态_Windows10网络和共享中心
2026-01-01
致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。