fputcsv是PHP中将数组格式化为CSV并写入已打开文件指针的函数,需先用fopen打开文件,传入索引数组,自动处理转义与引号封装,返回写入长度或false。

写入 CSV 文件时,fputcsv 的基本调用方式
fputcsv 本质是把数组转成 CSV 格式字符串,并写入已打开的文件指针。它不负责打开或关闭文件,也不自动创建文件——你得先用 fopen 打开一个可写的流(比如 'w' 或 'a' 模式),再传给它。
最简可用示例:
$fp = fopen('data.csv', 'w');
fputcsv($fp, ['name', 'age', 'city']);
fputcsv($fp, ['Alice', '30', 'Beijing']);
fclose($fp);
注意:第二参数必须是索引数组(['a','b','c']),不能是关联数组(['name'=>'Alice'])——否则字段顺序不可控,且键名不会被写入。
处理中文、特殊字符和编码问题
PHP 默认不处理字符编码,如果源数据是 UTF-8,而 Excel 默认用 GBK 打开,就会乱码。这不是 fputcsv 的 bug,而是 Windows Excel 的历史遗留行为。
立即学习“PHP免费学习笔记(深入)”;
解决方法不是改函数参数,而是往文件开头加 BOM 头(仅限 UTF-8):
Miller (mlr) 是一个命令行工具,用于查询、整形和重新格式化名称索引数据,如 CSV、TSV、JSON 和 JSON Lines。它将 awk、sed、cut、join 和 sort 的功能整合到一个专为结构化数据处理而构建的单一工具中。
$fp = fopen('data.csv', 'w');
fwrite($fp, ""); // 写入 UTF-8 BOM
fputcsv($fp, ['姓名', '年龄', '城市']);
fputcsv($fp, ['张三', '28', '上海']);
fclose($fp);
-
fputcsv本身不转义、不编码转换,只按字节原样输出; - 确保你的 PHP 文件保存为 UTF-8 无 BOM,但写入时手动加 BOM;
- 避免用
mb_convert_encoding转成 GBK——Excel 对 GBK CSV 支持不稳定,BOM + UTF-8 是目前最兼容方案。
分隔符、封装符、转义符怎么自定义
fputcsv 第三、四、五个参数分别控制分隔符(delimiter)、封装符(enclosure)、转义符(escape_char)。默认是逗号、双引号、双引号。
常见调整场景:
- 想用制表符做分隔符(TSV):
fputcsv($fp, $row, " "); - 字段里含双引号又不想被封装:
fputcsv($fp, $row, ',', "'", '\')(改用单引号封装,反斜杠转义); - 注意:PHP 8.1+ 开始,第五个参数(
escape_char)设为""(空字符串)会禁用转义,但某些旧版本不支持,慎用。
只要字段中不含分隔符、换行符或封装符,就不用封装;fputcsv 会自动判断是否需要加引号——你不用自己拼字符串。
内存占用大、写入慢?别用 fputcsv 处理超大数据
fputcsv 是逐行写入,看起来“流式”,但它内部仍会临时拼接整行字符串再写入。当某一行字段极长(比如含 Base64 图片),或单字段含大量换行符时,PHP 字符串内存开销会上升明显。
更稳的做法:
- 用
fwrite手动拼接简单 CSV(无嵌套引号需求时); - 对百万级行数,优先考虑生成临时文件后用 shell 命令压缩/拆分(如
split),而非在 PHP 中缓存; -
fputcsv不支持“跳过空行”或“条件过滤”,逻辑复杂时建议先array_filter再写入,别塞进回调里折腾。
真正容易被忽略的是:它不会帮你处理 null、false、0 这些值的语义——fputcsv($fp, [null, false, 0]) 会写出 ,,,而不是留空或占位符。业务上需要统一转换的,得提前 array_map 处理好。


















