PHP处理CSV重复EAN值:筛选最低价商品并去重
解决CSV重复EAN保留最低价行的问题
我来帮你搞定这个需求!你现在的代码思路有点绕,而且每次循环都重新读取整个文件,效率特别低,逻辑也没抓准核心——我们其实只需要按EAN分组,跟踪每个EAN对应的最低价行就可以了。
先说说你现有代码的问题
- 每次
while循环里都调用file('./test.csv'),相当于每读一行就把整个文件加载一遍,67个字段+大量行的话,性能会崩掉 - 判断
count > 2的逻辑不对,没法准确识别重复EAN并比较价格
正确的实现思路
- 先读取CSV的表头,最后要保留它
- 用一个关联数组,以EAN为键,存储每个EAN对应的最低价格和完整行数据
- 遍历所有数据行,跳过表头:
- 提取当前行的EAN和价格(注意把价格转成数字,避免字符串比较的坑)
- 如果这个EAN第一次出现,直接存入数组
- 如果已经存在,就比较当前价格和数组里的价格,更低的话就替换成当前行
- 最后把表头和数组里的所有最低价行写入新的CSV文件
完整代码实现
<?php $inputFile = './test.csv'; $outputFile = './output.csv'; $delimiter = ';'; // 你的CSV分隔符是分号,这里保持一致 // 第一步:读取表头 $file = fopen($inputFile, 'r'); $header = fgetcsv($file, 0, $delimiter); fclose($file); // 第二步:初始化数组,用来存每个EAN的最低价行 $eanTrack = []; // 第三步:重新打开文件处理数据行 $file = fopen($inputFile, 'r'); fgetcsv($file, 0, $delimiter); // 跳过表头行 while (($row = fgetcsv($file, 0, $delimiter)) !== false) { $currentEan = $row[2]; // EAN在索引2的位置,和你原来的逻辑一致 // 👉 这里要替换成你实际的价格字段索引!比如价格在第6列(索引5)就写$row[5] $currentPrice = (float)$row[5]; // 如果这个EAN还没被记录,直接存进去 if (!isset($eanTrack[$currentEan])) { $eanTrack[$currentEan] = [ 'lowestPrice' => $currentPrice, 'rowData' => $row ]; } else { // 对比价格,当前行更便宜的话就替换 if ($currentPrice < $eanTrack[$currentEan]['lowestPrice']) { $eanTrack[$currentEan]['lowestPrice'] = $currentPrice; $eanTrack[$currentEan]['rowData'] = $row; } } } fclose($file); // 第四步:把结果写入新的CSV $output = fopen($outputFile, 'w'); // 先写表头 fputcsv($output, $header, $delimiter); // 再写每个EAN的最低价行 foreach ($eanTrack as $item) { fputcsv($output, $item['rowData'], $delimiter); } fclose($output); echo "处理完成!结果文件已保存到:{$outputFile}"; ?>
关键注意事项
- 价格字段索引:一定要把代码里的
$row[5]替换成你CSV中价格字段的实际索引(从0开始计数) - 价格格式处理:如果你的价格带货币符号(比如€、$)或者千分位逗号,要先清洗,比如:
// 示例:去掉欧元符号和千分位逗号 $priceStr = str_replace(['€', ','], ['', '.'], $row[5]); $currentPrice = (float)$priceStr; - 安全起见:代码会生成新的输出文件,不会修改原CSV,你可以先用测试文件验证逻辑没问题再处理正式文件
内容的提问来源于stack exchange,提问作者Qhiliqq
相关产品推荐
相关产品推荐

