PHP 动态过滤 CSV 行中值为 0 的列并保留对应表头

6次阅读

PHP 动态过滤 CSV 行中值为 0 的列并保留对应表头

本文介绍如何在 php 中根据匹配条件筛选 csv 数据后,**动态识别并移除每行中值为 0 的数值列(如鞋码库存)**,同时同步精简表头,实现“按行定制化列结构”的灵活处理。

在实际业务场景中(例如鞋类库存导出),csv 文件常包含大量尺寸列(如 31–38),但不同商品仅在部分尺码有库存。若直接导出全部列,会带来冗余和可读性问题。理想的处理方式是:对每一匹配行,仅保留库存 > 0 的尺寸列,并动态生成对应的精简表头与数据行

上述需求可通过 array_combine() + array_filter() 组合高效实现。关键在于:将表头($keys)与当前数据行($line)配对成关联数组,再利用 array_filter() 默认行为(过滤掉 0、””、NULL、false 等 falsy 值)剔除库存为 0 的项——这正是本方案的核心逻辑。

以下是优化后的完整代码段(含健壮性增强):

$csvContent = file_get_contents($_SERVER['DOCUMENT_ROOT'] . '/CsvTest/Sortiment.csv'); $input = 'Company'; $value = 'Dockers';  // 解析 CSV:按行分割 → 拆分为 CSV 数组 $rows = array_map('str_getcsv', explode(PHP_EOL, trim($csvContent))); if (empty($rows)) {     throw new RuntimeException('CSV is empty or malformed.'); }  $keys = array_shift($rows); // 提取表头 $keyIndex = array_search($input, $keys); if ($keyIndex === false) {     throw new InvalidArgumentException("Column '{$input}' not found in CSV header."); }  $sortiment_array = []; foreach ($rows as $line) {     // 跳过空行或无效行     if (!is_array($line) || count($line) !== count($keys)) continue;      if (isset($line[$keyIndex]) && $line[$keyIndex] === $value) {         // 关键步骤:用表头与数据行构建关联数组,并过滤掉值为 0(及其它 falsy)的项         $combined = array_combine($keys, $line);         // 注意:array_filter 会保留键名,且默认过滤 falsy 值(0 会被移除)         $filtered = array_filter($combined, function($v) {             // 显式判断:只过滤严格等于字符串 "0" 或整数 0,避免误删 "0.5"、"001" 等             return $v !== '0' && $v !== 0 && $v !== '';         });          $sortiment_array[] = [             'shoe size' => implode(',', array_keys($filtered)),             'sortiment' => implode(',', $filtered)         ];     } }

输出效果示例(对应原始数据中两行 dockers):

立即学习PHP免费学习笔记(深入)”;

array(2) {   [0] => array(2) {     ["shoe size"] => string(42) "Company,Produkt,Sortiment name,31,32,33,34,35,36"     ["sortiment"] => string(37) "Dockers,AD1234,Sort A,2,3,5,3,2,1"   }   [1] => array(2) {     ["shoe size"] => string(45) "Company,Produkt,Sortiment name,32,33,34,35,36,38"     ["sortiment"] => string(37) "Dockers,AE1234,Sort D,1,2,3,4,1,2"   } }

⚠️ 注意事项

  • array_filter() 默认会移除所有 falsy 值(包括 0, “”, null, false)。若 CSV 中存在合法的空字符串(如未填写的备注字段)或需保留 “0” 字符串(非数值零),请务必使用显式回调函数(如上所示)进行精准判断。
  • 确保 $keys 与 $line 长度一致,否则 array_combine() 将返回 false;建议添加 count() 校验。
  • 若需支持多匹配值(如 [‘Dockers’, ‘Nike’]),可将 $value 改为数组,并用 in_array($line[$keyIndex], $values) 替代严格相等判断。

该方案简洁、高效、可扩展,完美契合“按行动态裁剪列”的典型数据清洗需求。

text=ZqhQzanResources