PHP遍历查询结果按prefix键分组合并重复值代码排错
问题根因
现有代码存在3个核心错误,导致分组合并逻辑完全失效:
- 字段名不匹配:写入
$translate_array时使用的键名是prefix,但查找重复项时array_column提取的是不存在的connector_prefix键,array_search永远返回false,所有条目都会被判定为新prefix直接新增,永远走不到合并分支。 - 判断逻辑存在隐式转换bug:
array_search匹配成功时会返回对应元素的数字索引,若匹配到索引为0的首元素,!array_search(...)会因为!0 == true误判为“不存在重复项”,必须使用严格不等于false的规则判断结果。 - 合并逻辑定位错误+类型不匹配:用
$i-1定位重复prefix的位置完全不可靠(重复项不一定紧邻上一条记录);首次写入translate_hostname时存的是字符串类型,直接追加值会产生类型错误,且和预期的子数组结构不匹配。
修复方案
推荐用prefix作为临时关联键实现分组,避免每次循环全量遍历已存数组做查找,性能更高逻辑也更简洁,代码如下:
$translate_array = []; // 初始化prefix到数组索引的映射,避免重复查找 $prefixMap = []; while (($arr = $_opDB->fetch_assoc($result)) !== FALSE) { $currentPrefix = $arr['base_name']; $currentTranslateItem = [ 'translate' => $arr['translate_hostname'] ]; // 不存在当前prefix则新建分组 if (!isset($prefixMap[$currentPrefix])) { $prefixMap[$currentPrefix] = count($translate_array); $translate_array[] = [ 'prefix' => $currentPrefix, // 首次写入就使用数组结构,和后续追加逻辑统一 'translate_hostname' => [$currentTranslateItem] ]; } else { // 直接通过映射找到对应索引追加内容 $targetIndex = $prefixMap[$currentPrefix]; $translate_array[$targetIndex]['translate_hostname'][] = $currentTranslateItem; } } // 如果需要重置数组为连续数字索引,可执行这行 $translate_array = array_values($translate_array);
如果不使用临时映射,也可以直接修复原逻辑的错误点,但结果集较大时查找性能会明显下降:
$translate_array = []; while (($arr = $_opDB->fetch_assoc($result)) !== FALSE) { $currentPrefix = $arr['base_name']; // 注意列名和写入的prefix键保持一致,使用严格比较判断查找结果 $existIndex = array_search($currentPrefix, array_column($translate_array, 'prefix')); if ($existIndex === false) { $translate_array[] = [ 'prefix' => $currentPrefix, 'translate_hostname' => [ ['translate' => $arr['translate_hostname']] ] ]; } else { // 用实际匹配到的索引定位,不要用$i-1的错误定位逻辑 $translate_array[$existIndex]['translate_hostname'][] = [ 'translate' => $arr['translate_hostname'] ]; } }
最终效果
修复后prefix为DD的两条记录会生成符合预期的结构:
[3] => Array ( [prefix] => DD [translate_hostname] => Array ( [0] => Array ( [translate] => dd ) [1] => Array ( [translate] => de ) ) )
内容的提问来源于stack exchange,提问作者B. Christophe
相关产品推荐
相关产品推荐

