PHP上传CSV文件行数统计异常(295行显示926行)如何修复?
解决CSV文件上传后行数统计错误的问题
你的代码在统计CSV行数时出现了偏差,实际295行却统计出926行,这大概率是换行符解析或CSV格式识别的问题导致的,我来帮你分析并修复:
问题根源
你用fgets()逐行读取文件,但这个函数有两个关键局限性:
- 换行符不兼容:不同操作系统的换行符格式不同(Windows是
\r\n,Unix/Linux是\n,旧版Mac是\r),fgets()会把\r和\n都当作独立的换行标记,导致一行被拆成多次读取,行数被重复统计。 - 无法识别CSV多行单元格:如果你的CSV里存在带双引号的单元格(比如单元格内容包含换行),
fgets()会把单元格内的换行当成新行,错误地增加行数统计。
修复方案
推荐使用PHP专门的CSV处理函数fgetcsv(),它能正确解析CSV格式,自动识别带引号的多行单元格,同时兼容不同系统的换行符。
修改后的完整代码如下:
<?php if(isset($_POST['upload'])) { $filename = $_FILES['files']['name']; $path = "upload_enq/"; // 先检查上传目录是否存在,不存在则创建 if (!is_dir($path)) { mkdir($path, 0755, true); } $targetPath = $path . basename($filename); if(move_uploaded_file($_FILES['files']['tmp_name'], $targetPath)){ $rowCount = 0; $fileObj = fopen($targetPath, "rt"); if($fileObj){ // 用fgetcsv逐行读取,自动处理CSV格式 while(($row = fgetcsv($fileObj)) !== false){ $rowCount++; } fclose($fileObj); echo "CSV文件实际行数:" . $rowCount; } else { echo "无法打开上传的文件,请检查权限"; } } else { echo "文件上传失败,请重试"; } } ?> <form class="forms-sample" method="post" enctype="multipart/form-data"> <input type="file" name="files" id="files" accept=".csv" /> <!-- 限制仅上传CSV文件 --> <input type="submit" class="btn btn-success mr-2" name="upload" id="upload" value="Upload" /> </form>
额外优化细节
- 增加了目录自动创建:避免因
upload_enq目录不存在导致上传失败; - 补充了上传结果验证:针对文件上传、文件打开失败的情况给出明确提示;
- 添加了文件类型限制:通过
accept=".csv"让用户只能选择CSV文件,减少无效上传。
如果你的CSV确定没有多行单元格,只是换行符问题,也可以用更简洁的方式统计:
// 替换原有的fopen和while循环部分 $lines = file($targetPath, FILE_SKIP_EMPTY_LINES | FILE_IGNORE_NEW_LINES); $rowCount = count($lines);
但这个方法无法处理带多行单元格的CSV,所以优先推荐fgetcsv()的方案。
内容的提问来源于stack exchange,提问作者omkara
相关产品推荐
相关产品推荐

