PHP关联数组重复元素问题:无法向已有数组追加属性
问题:合并两个CSV的PC信息时,关联数组属性未追加反而生成重复键
尝试提取两个CSV中的PC信息,构建以PC名称为键、属性为值的关联数组。处理第一个CSV时正常,但第二个CSV的新属性未追加到已有数组,而是生成同名的新数组。
第一部分代码(符合预期)
if($_FILES['panda']['error'] == 0){ $pandaExt = strtolower(end(explode('.', $_FILES['panda']['name']))); $pandaTmpName = $_FILES['panda']['tmp_name']; if($pandaExt === 'csv'){ $pandaHandle = @fopen($pandaTmpName, "r"); if ($pandaHandle) { fgetcsv($pandaHandle, 0, "\t"); while (($row = fgetcsv($pandaHandle, 0, "\t")) !== false) { switch ($row[1]) { case "Server": $servers[$row[2]]["Name"] = $row[2]; break; default: $computers[$row[2]]["Name"] = $row[2]; $computers[$row[2]]["Type"] = $row[1]; $computers[$row[2]]["AV"] = $row[20]; $computers[$row[2]]["OS"] = $row[14]; $computers[$row[2]]["LastUser"] = $row[40]; $computers[$row[2]]["LastSeen"] = $row[12]; break; } } fclose($pandaHandle); } } }
第二部分代码(产生重复数组)
if($_FILES['ncentral']['error'] == 0){ $ncentralExt = strtolower(end(explode('.', $_FILES['ncentral']['name']))); $ncentralTmpName = $_FILES['ncentral']['tmp_name']; if($ncentralExt === 'csv'){ $ncentralHandle = @fopen($ncentralTmpName, "r"); if ($ncentralHandle) { for($i=0;$i<7;$i++) { fgetcsv($ncentralHandle, 0, ","); } while (($row = fgetcsv($ncentralHandle, 0, ",")) !== false) { if($row[1] == "Application" && $row[2] == "Display Name") { array_push($applications[$row[3]],$row[0]); } if($row[1] == "BIOS" && $row[2] == "Serial number") { $computers[$row[0]]["Serial"] = $row[3]; } } fclose($ncentralHandle); } } }
最终输出的$computers数组
[CADUSER-PC] => Array ( [Name] => CADUSER-PC [Type] => Workstation [AV] => data [OS] => data [LastUser] => data [LastSeen] => data ) [CADUSER-PC] => Array ( [Serial] => data )
问题原因
PHP关联数组的键区分大小写和首尾空格,看起来相同的键名实际可能存在差异:
- 第一个CSV中的PC名称可能是
CADUSER-PC,第二个CSV中的是caduser-pc(大小写不同) - 或者其中一个键名带有首尾空格,比如
CADUSER-PC或CADUSER-PC - 这两种情况都会被PHP视为不同的键,从而生成两个独立的数组条目。
解决方案
统一PC名称的格式,对两个CSV中的键名做标准化处理,确保完全一致:
1. 定义标准化函数
添加一个函数来统一处理PC名称:
function normalizePcName($name) { // 去除首尾空格 + 转小写,可根据需求添加其他规则(比如替换特殊字符) return trim(strtolower($name)); }
2. 修改第一部分代码
将所有$row[2]替换为标准化后的名称:
default: $pcName = normalizePcName($row[2]); $computers[$pcName]["Name"] = $row[2]; $computers[$pcName]["Type"] = $row[1]; $computers[$pcName]["AV"] = $row[20]; $computers[$pcName]["OS"] = $row[14]; $computers[$pcName]["LastUser"] = $row[40]; $computers[$pcName]["LastSeen"] = $row[12]; break;
3. 修改第二部分代码
将$row[0]替换为标准化后的名称:
if($row[1] == "BIOS" && $row[2] == "Serial number") { $pcName = normalizePcName($row[0]); $computers[$pcName]["Serial"] = $row[3]; }
修改后,无论原始CSV中的PC名称大小写或空格如何,都会被统一为相同的键,新属性将正确追加到已有数组中。
内容的提问来源于stack exchange,提问作者DeanKellham
相关产品推荐
相关产品推荐

