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

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&nbsp;&nbsp;&nbsp;&nbsp;ID&nbsp;&nbsp;&nbsp;&nbsp;Item picked&nbsp;&nbsp;&nbsp;&nbsp;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 . "&nbsp;&nbsp;&nbsp;&nbsp;" . $nameEmp. "&nbsp;&nbsp;&nbsp;&nbsp;" . $itemPacked. "&nbsp;&nbsp;&nbsp;&nbsp;" . round($perCal, 0) . "%" . "<br>";
}
?>

效果说明

修复后会先遍历所有CSV行统计每个员工的总打包量,第二次遍历输出时判断是否为该员工的最后一条记录,是则输出累计总和,否则留空,和给出的期望输出完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 21:06:00