You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中使用PHP读取CSV文件返回二进制字符串问题

解决Laravel读取CSV时输出含空字节单元素数组的问题

问题原因

输出里的ÿþ是UTF-16LE编码的字节顺序标记(BOM),\x00是UTF-16编码的空字节,同时内容中的\t说明这其实是制表符分隔的文件(TSV),并非逗号分隔的标准CSV。而fgetcsv默认以逗号为分隔符,且不支持UTF-16这类双字节编码,因此会把整行内容识别为单个元素,同时保留编码相关的乱码。

解决方案

方法1:读取后转编码+指定制表符分隔

直接读取文件内容并转换编码,再按制表符分割数据:

$filePath = Storage::path('email_ingested_data/data/Report.csv');
// 读取文件并将UTF-16LE编码转为UTF-8
$content = mb_convert_encoding(file_get_contents($filePath), 'UTF-8', 'UTF-16LE');
// 按行拆分内容
$lines = explode("\n", trim($content));
// 用制表符作为分隔符解析表头
$header = str_getcsv($lines[0], "\t");
dd($header);

方法2:通过编码转换流读取

利用PHP的过滤流直接转换编码,同时指定分隔符:

$filePath = Storage::path('email_ingested_data/data/Report.csv');
// 打开带编码转换的文件流,将UTF-16LE转为UTF-8
$file = fopen("php://filter/read=convert.iconv.UTF-16LE/UTF-8/resource=$filePath", 'r');
// 设置制表符为分隔符,读取表头
fgetcsv($file, 0, "\t");
$csv = fgetcsv($file, 0, "\t");
dd($csv);

方法3:Laravel Storage直接处理

用Laravel的Storage门面读取内容后处理编码和分隔:

$content = Storage::get('email_ingested_data/data/Report.csv');
// 移除UTF-16的BOM并转换编码为UTF-8
$content = preg_replace('/^\x{FEFF}/u', '', mb_convert_encoding($content, 'UTF-8', 'UTF-16LE'));
// 按行拆分并逐行用制表符解析
$rows = array_map(function($row) {
    return str_getcsv($row, "\t");
}, explode("\n", trim($content)));
dd($rows[0]);

验证提示

  • 可通过IDE查看文件编码(比如VS Code右下角的编码标识),确认是否为UTF-16LE,确保转换编码参数匹配。
  • 必须指定制表符"\t"作为解析分隔符,否则工具会默认用逗号拆分,导致整行被识别为单个元素。

内容的提问来源于stack exchange,提问作者Elliott Coe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 01:15:40