PHP按Category汇总CSV数据时遇字符串数值运算错误求助
问题描述
我用PHP读取CSV文件,已经能计算每条数据的Price和Quantity的乘积并输出单条结果,但现在需要按Category字段汇总同类型的计算结果,期望输出格式如下:
Hotel: 230 Food: 84.04 Fuel: 186
但一直碰到字符串与整数(或类似类型)的运算错误,我的代码如下:
<!DOCTYPE html> <html> <body> <center> <h1>DISPLAY DATA PRESENT IN CSV</h1> <h3>CSV File</h3> <?php echo "<html><body><center><table> "; // $fileName = $_POST['csvfile']; // $fileName = "./test.csv"; // $summary = array(); $i = 0; // $index = null; // $file = fopen($fileName, "r"); $array = $fields = array(); $handle = @fopen("test.csv", "r"); if($handle){ while(($row = fgetcsv($handle, 4096)) !== False){ if(empty($fields)){ $fields = $row; continue; } foreach($row as $k=>$value){ $array[$i][$fields[$k]] = $value; } $i++; } if(!feof($handle)){ echo "Error: unexpected fgets() fail "; } fclose($handle); } foreach($array as $key => $value){ for($a = 0; $a < 1; $a++){ if($value['Category'] == $value['Category']){ echo $value['Category'] . ": " . ($value['Quantity'] * $value['Price']) . "<br>"; } else{ echo $value['Category'] . ": " . ($value['Quantity'] * $value['Price']) . "<br>"; } } } echo "<br>"; print_r($array); $sumArray = array(); foreach($array as $k=>$subArray){ foreach($subArray as $key=>$value){ $sumArray['Category'] += $value; } } print($sumArray); echo " </table></center></body></html>"; ?> </center> </body> </html>
问题排查与解决方案
核心问题分析
- 类型转换问题:CSV读取的
Price和Quantity默认是字符串类型,若数据带货币符号、千分位逗号等格式,直接相乘会触发类型运算错误。 - 汇总逻辑错误:原代码的
$sumArray处理逻辑完全错误,未按Category分组,盲目累加所有字段值,必然引发字符串与数字的运算冲突。 - 冗余代码:循环内的
if($value['Category'] == $value['Category'])无意义,条件永远为真。
修正后的代码
<!DOCTYPE html> <html> <body> <center> <h1>DISPLAY DATA PRESENT IN CSV</h1> <h3>CSV File</h3> <?php echo "<html><body><center>"; $array = $fields = []; $handle = fopen("test.csv", "r"); if($handle){ // 读取表头 $fields = fgetcsv($handle, 4096); // 读取数据行并处理类型 while(($row = fgetcsv($handle, 4096)) !== false){ $data = []; foreach($row as $k => $value){ $fieldName = $fields[$k]; // 对Price和Quantity做数值转换,清除非数字字符 if(in_array($fieldName, ['Price', 'Quantity'])){ $value = (float)preg_replace('/[^0-9.]/', '', $value); } $data[$fieldName] = $value; } $array[] = $data; } fclose($handle); } // 按Category分类汇总 $categorySum = []; foreach($array as $item){ $category = $item['Category']; $itemTotal = $item['Quantity'] * $item['Price']; // 累加对应分类的总金额 if(isset($categorySum[$category])){ $categorySum[$category] += $itemTotal; } else { $categorySum[$category] = $itemTotal; } } // 格式化输出汇总结果 echo "<h3>分类汇总结果</h3>"; foreach($categorySum as $category => $total){ // 整数输出无小数,浮点数保留两位 $formattedTotal = is_int($total) ? (int)$total : number_format($total, 2); echo "{$category}: {$formattedTotal}<br>"; } echo "</center></body></html>"; ?> </center> </body> </html>
关键改进点
- 类型安全处理:用
preg_replace清除Price中的非数字字符(如$、,),强制转为浮点数,确保运算时为数值类型。 - 正确的汇总逻辑:创建
$categorySum数组,以Category为键,累加对应分类的Quantity*Price结果。 - 格式化输出:根据汇总结果类型调整显示格式,匹配期望的输出样式。
- 精简冗余代码:移除无意义的条件判断和多余循环,优化CSV读取流程。
内容的提问来源于stack exchange,提问作者Omen
相关产品推荐
相关产品推荐

