PHP读取CSV文件统计员工打包总数时累加功能不生效问题求助
问题排查及修复方案
错误原因
- 核心错误:
$sumArray = array();写在while循环内部,每次遍历csv行都会把之前的累加结果清空重置成空数组,自然无法累计数值 - 逻辑范围错误:累加、计算、输出逻辑全部包裹在
if (!isset($sumArray[$nameEmp]))判断内,只有第一次遇到对应员工ID时才会执行,后续同ID的行不会触发累加 - 语法隐患:CSV列名作为数组键时未加引号,
$data[Start]这类写法会将Start识别为常量,未定义常量时才会 fallback 为字符串,容易引发报错 - 变量未定义:代码中
$perMin、$precentEff两个变量未提前赋值,直接使用会抛出Notice级别错误,影响计算结果 - 输出逻辑不符预期:原代码每次累加后都会直接输出总数值,而需求是仅在员工ID最后一次出现时才展示累计总和,其余行对应位置留空
修复后代码
<?php // 提前定义未初始化的变量,此处数值可根据实际业务调整 $perMin = 1; $precentEff = 100; // 统计数组放在循环外初始化 $sumArray = array(); // 先遍历一次CSV,统计每个员工的总打包量,避免边遍历边判断是否是最后一次出现 $allData = array(); if (($handle = fopen("packing.csv", "r")) !== FALSE) { // 跳过表头行,根据实际CSV是否有表头调整 fgetcsv($handle); while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { $allData[] = $data; $nameEmp = $data[3]; // Employee对应第4列,索引从0开始,根据实际列顺序调整 $itemPacked = (int)$data[2]; // Item对应第3列,根据实际调整 if (!isset($sumArray[$nameEmp])) { $sumArray[$nameEmp] = 0; } $sumArray[$nameEmp] += $itemPacked; } fclose($handle); } // 记录每个员工已经输出的次数,用于判断是否是最后一次 $empCount = array(); // 输出表头 echo "Total for Each ID ID Item picked Perc<br>"; foreach ($allData as $data) { $startTime = $data[0]; // Start对应第1列 $endTime = $data[1]; // Finish对应第2列 $itemPacked = (int)$data[2]; $nameEmp = $data[3]; $startParts = explode(":", $startTime); $endParts = explode(":", $endTime); $startMinute = (int)$startParts[1]; $startHour = (int)$startParts[0]; $endMinute = (int)$endParts[1]; $endHour = (int)$endParts[0]; $differenceHour = ($endHour - $startHour); $differenceMinute = ($endMinute - $startMinute); $differenceHour -= (($differenceMinute < 0) ? 1 : 0); if ($differenceMinute < 0) { $differenceMinute += 60; } $difference = $differenceHour * 60 + $differenceMinute; $pickedRate = $perMin * $itemPacked; $perCal = $pickedRate / $difference * $precentEff; // 统计当前员工已经输出的行数 if (!isset($empCount[$nameEmp])) { $empCount[$nameEmp] = 0; } $empCount[$nameEmp]++; // 计算当前员工总共有多少行记录 $totalEmpRows = count(array_filter($allData, function($row) use ($nameEmp) { return $row[3] == $nameEmp; })); // 如果是最后一次出现就输出总和,否则输出空格 $totalShow = $empCount[$nameEmp] == $totalEmpRows ? $sumArray[$nameEmp] : ""; echo $totalShow . " " . $nameEmp. " " . $itemPacked. " " . round($perCal, 0) . "%" . "<br>"; } ?>
效果说明
修复后会先遍历所有CSV行统计每个员工的总打包量,第二次遍历输出时判断是否为该员工的最后一条记录,是则输出累计总和,否则留空,和给出的期望输出完全一致。
内容的提问来源于stack exchange,提问作者stoperan
相关产品推荐
相关产品推荐

