PHP中如何用UNION ALL实现用户与管理员会话的匹配查询
基于accesstoken和userid的会话查询实现(UNION ALL方案)
核心SQL实现
通过UNION ALL合并用户会话与管理员会话的查询结果,再通过排序和条数限制,实现"优先返回用户会话,无用户会话则返回管理员会话"的需求:
SELECT 'user' AS session_type, u.id AS id, u.username, -- 替换为users表实际字段 s.accesstoken, s.expire_time -- 替换为sessions表实际字段 FROM users u INNER JOIN sessions s ON u.id = s.userid WHERE s.accesstoken = ? AND u.id = ? UNION ALL SELECT 'admin' AS session_type, a.id AS id, a.admin_name, -- 替换为admin表实际字段 asess.accesstoken, asess.expire_time -- 替换为adminsessions表实际字段 FROM admin a INNER JOIN adminsessions asess ON a.id = asess.userid WHERE asess.accesstoken = ? AND a.id = ? -- 让用户会话排在结果最前面,优先返回 ORDER BY session_type = 'user' DESC LIMIT 1;
SQL逻辑说明
- 第一个查询块关联
users和sessions表,筛选符合条件的用户会话记录 - 第二个查询块关联
admin和adminsessions表,筛选符合条件的管理员会话记录 UNION ALL合并两个查询结果(不自动去重,保留所有匹配项)- 通过排序规则让用户会话优先展示,最后用
LIMIT 1确保只返回一条匹配数据
PHP代码实现(PDO方式,防SQL注入)
作为新手,用PDO操作数据库更安全,避免注入风险:
// 获取请求参数:URL中的accesstoken、请求头中的userid $accessToken = $_GET['accesstoken'] ?? ''; $userId = $_SERVER['HTTP_USERID'] ?? ''; // 参数校验 if (empty($accessToken) || empty($userId)) { header('HTTP/1.1 400 Bad Request'); echo json_encode(['error' => '缺少accesstoken或userid参数']); exit; } // 数据库连接配置(替换为你的实际信息) $dbConfig = [ 'dsn' => 'mysql:host=localhost;dbname=your_database;charset=utf8mb4', 'user' => 'your_db_user', 'pass' => 'your_db_password' ]; try { // 初始化PDO连接 $pdo = new PDO($dbConfig['dsn'], $dbConfig['user'], $dbConfig['pass']); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 准备SQL语句 $sql = " SELECT 'user' AS session_type, u.id AS id, u.username, s.accesstoken, s.expire_time FROM users u INNER JOIN sessions s ON u.id = s.userid WHERE s.accesstoken = ? AND u.id = ? UNION ALL SELECT 'admin' AS session_type, a.id AS id, a.admin_name, asess.accesstoken, asess.expire_time FROM admin a INNER JOIN adminsessions asess ON a.id = asess.userid WHERE asess.accesstoken = ? AND a.id = ? ORDER BY session_type = 'user' DESC LIMIT 1; "; // 绑定参数并执行查询 $stmt = $pdo->prepare($sql); $stmt->execute([$accessToken, $userId, $accessToken, $userId]); // 获取结果 $sessionData = $stmt->fetch(PDO::FETCH_ASSOC); if ($sessionData) { echo json_encode($sessionData); } else { header('HTTP/1.1 404 Not Found'); echo json_encode(['error' => '未找到匹配的会话记录']); } } catch (PDOException $e) { header('HTTP/1.1 500 Internal Server Error'); echo json_encode(['error' => '数据库操作失败:' . $e->getMessage()]); }
注意事项
- 替换代码中的数据库连接信息、表字段为你的实际业务配置
- 请求头
userid的获取:如果前端传递的是User-ID格式的请求头,PHP中对应$_SERVER['HTTP_USER_ID'],需和前端确认字段名 - 若需过滤过期会话,可在WHERE条件中添加
s.expire_time > NOW()(用户会话)和asess.expire_time > NOW()(管理员会话)
内容的提问来源于stack exchange,提问作者Santosh Kumar
相关产品推荐
相关产品推荐

