PHP处理CSV文件时数组索引赋值异常问题咨询
问题描述
我有一段PHP代码用于重新格式化CSV文件字符串,代码如下:
foreach ($rows as $key => &$row) { print $key; print "\n"; if ($row === count($rows) - 1) { break; } $columns = explode(";", $row); $columns[30] = str_replace('"', '', $columns[6]); // ItemTypeTxt $columns[29] = "Sandberg"; // BrandTxt $columns[19] = str_replace('"', '', $columns[3]); // Width $columns[18] = str_replace('"', '', $columns[4]); // Height $columns[16] = str_replace('"', '', $columns[2]); // Weight $columns[15] = "SDG"; // Brand $columns[12] = "SEK"; // Currency $columns[13] = round(floatval($columns[5]) * 0.2, 2); // Price $columns[11] = round(floatval($columns[5]) * 0.8, 2); // Price $columns[10] = round(floatval($columns[5]) * 0.8, 2); // Price $columns[4] = str_replace('"', '', $columns[1]); // Item $columns[2] = str_replace('"', '', $columns[0]); // ItemOEM $columns[1] = "1"; $columns[0] = "SDG" . str_replace('"', '', $columns[0]); // ItemID $columns[32] = "-"; $columns[31] = "-"; $columns[28] = "-"; $columns[27] = "-"; $columns[26] = "-"; $columns[25] = "-"; $columns[24] = "-"; $columns[23] = "-"; $columns[22] = "-"; $columns[21] = "-"; $columns[20] = "-"; $columns[17] = "-"; $columns[14] = "-"; $columns[9] = "-"; $columns[8] = "-"; $columns[7] = "-"; $columns[6] = "-"; $columns[5] = "-"; $columns[3] = "-"; // Unknown values // Puts together the row into a string $row = implode(";", $columns); print $row; }
注:print仅用于调试,循环结束后会将$rows数组合并到$current变量做后续处理。
代码运行后生成的示例输出:
SDG125-62;1;125-62;-;Sandberg Speak’n Go In-Earset Black;-;-;Hörlurar;Sandberg;1.1;2.5;19;SDG;SEK;0;0;0;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-
预期输出中索引3到9的元素都应为-,但实际索引4出现了本该赋值给索引10的值。我是PHP新手,怀疑是引用传递的特性导致问题,寻求解决方法。
解决方案
1. 修正循环终止判断逻辑
原代码中if ($row === count($rows) - 1)的判断完全错误:$row是CSV行的字符串内容,而count($rows)-1是数组的最后一个索引(数字),两者永远不可能相等,导致break从未触发,最后一行也会被错误处理。
将判断改为:
if ($key === count($rows) - 1) { break; }
这里$key是当前循环的数组索引(数字),和最后一个索引匹配时才终止循环。
2. 修复索引赋值遗漏问题
你的需求是索引3到9都设为-,但原代码先给$columns[4]赋值了内容,之后没有将其覆盖为-,这是索引4内容错误的直接原因。
在设置其他索引为-的代码块中,添加$columns[4] = "-";,确保索引3-9全部被覆盖:
$columns[9] = "-"; $columns[8] = "-"; $columns[7] = "-"; $columns[6] = "-"; $columns[5] = "-"; $columns[4] = "-"; // 新增这行,覆盖之前的赋值 $columns[3] = "-";
3. 解除foreach的引用绑定
使用foreach ($rows as $key => &$row)时,循环结束后$row仍然是对原数组最后一个元素的引用,如果后续代码中不小心修改$row,会意外改变原数组内容。因此循环结束后必须解除引用:
foreach ($rows as $key => &$row) { // ... 循环内代码 ... } unset($row); // 解除引用
修复后的完整代码
foreach ($rows as $key => &$row) { print $key; print "\n"; if ($key === count($rows) - 1) { break; } $columns = explode(";", $row); $columns[30] = str_replace('"', '', $columns[6]); // ItemTypeTxt $columns[29] = "Sandberg"; // BrandTxt $columns[19] = str_replace('"', '', $columns[3]); // Width $columns[18] = str_replace('"', '', $columns[4]); // Height $columns[16] = str_replace('"', '', $columns[2]); // Weight $columns[15] = "SDG"; // Brand $columns[12] = "SEK"; // Currency $columns[13] = round(floatval($columns[5]) * 0.2, 2); // Price $columns[11] = round(floatval($columns[5]) * 0.8, 2); // Price $columns[10] = round(floatval($columns[5]) * 0.8, 2); // Price $columns[2] = str_replace('"', '', $columns[0]); // ItemOEM $columns[1] = "1"; $columns[0] = "SDG" . str_replace('"', '', $columns[0]); // ItemID // 先处理需要保留的赋值,再统一设置要置为"-"的索引 $columns[32] = "-"; $columns[31] = "-"; $columns[28] = "-"; $columns[27] = "-"; $columns[26] = "-"; $columns[25] = "-"; $columns[24] = "-"; $columns[23] = "-"; $columns[22] = "-"; $columns[21] = "-"; $columns[20] = "-"; $columns[17] = "-"; $columns[14] = "-"; $columns[9] = "-"; $columns[8] = "-"; $columns[7] = "-"; $columns[6] = "-"; $columns[5] = "-"; $columns[4] = "-"; // 新增:将索引4置为"-" $columns[3] = "-"; // Unknown values $row = implode(";", $columns); print $row; } unset($row); // 解除引用
内容的提问来源于stack exchange,提问作者Simon Tuomi
相关产品推荐
相关产品推荐

