PHP:从指定CSV文件匹配字段并生成新CSV的功能实现咨询
PHP:从指定CSV文件匹配字段并生成新CSV的功能实现咨询
看起来你已经搞定了CSV转换的核心逻辑,现在就差跨文件的字段匹配这一步啦!我们可以通过提前把allSkuRO.csv的数据加载到一个关联数组的方式,高效完成这个匹配检查,这样不用每次循环都去读一遍文件,性能会好很多。
实现思路
- 先预处理
allSkuRO.csv:把文件里的PRODUCTCODE作为键,对应的sku作为值,存入一个关联数组(比如$skuMap),这样后续查询匹配的时间复杂度就是O(1)。 - 在生成新CSV的循环里,每次拿到
$subFields[0]后,去$skuMap里查找对应的sku值——如果找到就用这个值,没找到的话可以保留原$subFields[0](或者根据你的需求跳过该行)。
修改后的完整代码
<?php // 定义文件路径 $checkFile = "allSkuRO.csv"; $inputFile = "product_stock_ro.csv"; $outputFile = "updateStock_qty_ro.csv"; // -------------------------- // 第一步:预处理allSkuRO.csv,生成PRODUCTCODE到sku的映射 // -------------------------- $skuMap = []; $checkHandle = fopen($checkFile, 'r'); if (!$checkHandle) { die("无法打开文件:$checkFile"); } // 读取checkFile的表头 $checkHeaders = fgetcsv($checkHandle); // 确认表头里包含PRODUCTCODE和sku列(避免文件结构变化导致错误) $productCodeIndex = array_search('PRODUCTCODE', $checkHeaders); $skuIndex = array_search('sku', $checkHeaders); if ($productCodeIndex === false || $skuIndex === false) { die("allSkuRO.csv中缺少必要的列:PRODUCTCODE或sku"); } // 循环读取每一行,构建映射数组 while (false !== $checkFields = fgetcsv($checkHandle)) { $productCode = trim($checkFields[$productCodeIndex]); $sku = trim($checkFields[$skuIndex]); // 跳过PRODUCTCODE为空的行 if (!empty($productCode)) { // 如果有重复的PRODUCTCODE,后面的会覆盖前面的,确保PRODUCTCODE唯一 $skuMap[$productCode] = $sku; } } fclose($checkHandle); // -------------------------- // 第二步:处理输入文件,生成新的CSV // -------------------------- $inputHandle = fopen($inputFile, 'r'); $outputHandle = fopen($outputFile, 'w'); if (!$inputHandle || !$outputHandle) { die("无法打开输入或输出文件"); } $headers = fgetcsv($inputHandle); // 写入新CSV的表头 fputcsv($outputHandle, ["sku", "qty", "dateproduzione1", "produzione1"]); while (false !== $fields = fgetcsv($inputHandle)) { $fields = array_combine($headers, $fields); foreach ($fields as $name => $field) { $field = trim($field); if (!empty($field)) { $subFields = explode(";", $field); // 检查当前subFields[0]是否在skuMap中 $matchedSku = isset($skuMap[$subFields[0]]) ? $skuMap[$subFields[0]] : $subFields[0]; // 写入匹配后的行 fputcsv($outputHandle, [$matchedSku, $subFields[2], $subFields[3], $subFields[5]]); } } } fclose($inputHandle); fclose($outputHandle); ?>
注意事项
- 重复PRODUCTCODE处理:如果
allSkuRO.csv里存在重复的PRODUCTCODE,后面的行会覆盖前面的映射关系,所以建议确保PRODUCTCODE列的值是唯一的。 - 表头大小写问题:代码里的
'PRODUCTCODE'和'sku'是区分大小写的,如果你的CSV表头是小写(比如productcode),记得修改对应的字符串。 - 错误处理:代码里添加了基础的文件打开检查和列存在检查,避免脚本因为文件问题直接崩溃,你可以根据实际需求扩展更多错误处理逻辑。
备注:内容来源于stack exchange,提问作者Jackom
相关产品推荐
相关产品推荐

