Joomla SQL双向匹配用户ID取对应列值及报错修复
双向好友关系查询实现与报错修复
核心需求梳理
- 表
#__user_memberlinks存储用户双向好友关系,uida/uidb存关联双方用户ID,usera/userb均为1时代表好友关系已双向确认 - 查询指定
$userID的所有已确认好友ID:若uida匹配目标ID则取uidb,若uidb匹配目标ID则取uida,最终合并为contact字段输出,用于后续关联用户信息生成联系人列表 - 修复现有代码的两个运行报错:
mysqli::stat(): Couldn't fetch mysqliNotice: unserialize(): Error at offset
现有代码问题
- 重复调用
$this->getDbo()获取数据库连接实例,部分Joomla环境下会导致连接引用失效,触发mysqli读取错误 - UNION拼接的两个子查询未严格对齐返回字段的数量、顺序、别名,后续读取数据时字段错位,触发反序列化报错
- 未对传入的
$userID做类型校验与转义,存在SQL注入风险 - 重复编写相同的表关联逻辑,代码冗余,执行效率低
优化后代码
无需拆分两个查询做UNION,通过CASE WHEN在单条查询内完成双向ID匹配,性能更高且结构稳定:
// 仅获取一次数据库连接,避免连接失效 $db = $this->getDbo(); $query = $db->getQuery(true); // 强制将用户ID转为整型,杜绝注入风险与语法错误 $userID = (int)$userID; $query->select( 'd.*, CASE WHEN d.uida = ' . $userID . ' THEN d.uidb WHEN d.uidb = ' . $userID . ' THEN d.uida END AS contact, uc.name AS uEditor, created_by.name AS creator_name, modified_by.name AS modifier_name' ) ->from('`#__user_memberlinks` AS d') ->where([ 'd.usera = 1', 'd.userb = 1', '(d.uida = ' . $userID . ' OR d.uidb = ' . $userID . ')' ]) // 关联附属用户信息,字段使用独立别名避免覆盖 ->join('LEFT', '#__users AS uc ON uc.id = d.checked_out') ->join('LEFT', '#__users AS created_by ON created_by.id = d.created_by') ->join('LEFT', '#__users AS modified_by ON modified_by.id = d.modified_by'); $db->setQuery($query); // 获取结果集 $contactList = $db->loadObjectList();
效果验证
以目标用户ID=222、示例表数据为例,查询返回的contact字段值为111、333、444、555,完全匹配该用户的所有双向确认好友。
报错修复说明
- 解决mysqli连接错误:全流程仅调用一次
getDbo()获取连接实例,不存在重复初始化导致的连接引用失效问题 - 解决反序列化报错:单查询返回的字段结构固定,不存在UNION查询常见的字段错位、类型不匹配问题,数据读取时不会出现解析异常
内容的提问来源于stack exchange,提问作者Rifbsss
相关产品推荐
相关产品推荐

