You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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逻辑说明

  1. 第一个查询块关联users和sessions表,筛选符合条件的用户会话记录
  2. 第二个查询块关联admin和adminsessions表,筛选符合条件的管理员会话记录
  3. UNION ALL合并两个查询结果(不自动去重,保留所有匹配项)
  4. 通过排序规则让用户会话优先展示,最后用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 06:05:19