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

如何实现仅展示分配给当前用户的考试数据?

问题分析与解决方案

当前代码的核心问题是SQL查询未过滤当前登录用户的已分配考试,直接从exams表取出所有考试数据,导致所有用户都能看到全部考试。要实现“仅展示分配给当前用户的考试”,需要结合用户分配关系表和当前登录用户的ID来过滤数据。

前提假设

假设存在一个用于记录考试与用户分配关系的表(例如exam_assignments),表结构至少包含:

  • exam_id:关联的考试ID
  • user_id:被分配该考试的用户ID

解决方案步骤

1. 修改SQL查询语句

将原查询改为关联用户分配表,仅获取当前登录用户被分配的考试:

session_start();
// 确保当前用户已登录,获取用户ID(需根据实际session存储字段调整)
$current_user_id = $_SESSION['user_id'] ?? null;

$title = "ExamList";
// 使用JOIN关联分配表,过滤当前用户的考试
$query = "SELECT e.id, e.title, e.no_questions, e.points, e.schedule, e.time_limit, e.link 
          FROM exams e
          JOIN exam_assignments ea ON e.id = ea.exam_id
          WHERE ea.user_id = $current_user_id";
$exams = get_data($query);

2. 修复SQL注入风险(关键优化)

原get_data函数直接执行传入的查询语句,存在严重的SQL注入风险。建议改用预处理语句:

function get_data($query, $params = []){
    $conn = db_connect();
    $stmt = $conn->prepare($query);
    
    // 绑定参数(如果有)
    if(!empty($params)){
        $types = str_repeat('i', count($params)); // 假设参数都是整数类型,根据实际调整
        $stmt->bind_param($types, ...$params);
    }
    
    $stmt->execute();
    $result = $stmt->get_result();
    $output = [];
    while($row = $result->fetch_assoc()){
        $output[$row['id']] = $row;
    }
    $stmt->close();
    $conn->close();
    return $output;
}  

// 调用时传入参数
$current_user_id = $_SESSION['user_id'] ?? null;
$query = "SELECT e.id, e.title, e.no_questions, e.points, e.schedule, e.time_limit, e.link 
          FROM exams e
          JOIN exam_assignments ea ON e.id = ea.exam_id
          WHERE ea.user_id = ?";
$exams = get_data($query, [$current_user_id]);

3. 增加登录状态校验

在获取考试数据前,先校验用户是否已登录,避免未登录用户访问:

session_start();
if(!isset($_SESSION['user_id'])){
    // 未登录,跳转到登录页或提示权限不足
    header("Location: login.php");
    exit;
}

最终修改后的完整代码片段

<?php
function get_data($query, $params = []){
    $conn = db_connect();
    $stmt = $conn->prepare($query);
    
    if(!empty($params)){
        $types = str_repeat('i', count($params));
        $stmt->bind_param($types, ...$params);
    }
    
    $stmt->execute();
    $result = $stmt->get_result();
    $output = [];
    while($row = $result->fetch_assoc()){
        $output[$row['id']] = $row;
    }
    $stmt->close();
    $conn->close();
    return $output;
}  

session_start();
// 校验登录状态
if(!isset($_SESSION['user_id'])){
    header("Location: login.php");
    exit;
}

$title = "ExamList";
$current_user_id = $_SESSION['user_id'];
// 关联分配表查询当前用户的考试
$query = "SELECT e.id, e.title, e.no_questions, e.points, e.schedule, e.time_limit, e.link 
          FROM exams e
          JOIN exam_assignments ea ON e.id = ea.exam_id
          WHERE ea.user_id = ?";
$exams = get_data($query, [$current_user_id]);
?>

<?php foreach($exams as $exam){?>
<div class="col-xl-3 col-md-6 mb-4">
    <div class="card border-round pink-gradient exam_card">
        <div class="card-body text-center">
            <h4><?php echo $exam['title']; ?></h4>

            <div class="btn-group dropright float-right">
                <button type="button" class="btn dropdown-toggle" data-toggle="dropdown"
                    aria-haspopup="true" aria-expanded="false">
                    <i class="fa fa-ellipsis-v" aria-hidden="true"></i>
                </button>
                <div class="dropdown-menu border-round pink-gradient dropdown_body">
                    <a href="examinees_result.php?id=<?php echo $exam['id']; ?>"
                        class="card_link">View</a>
                    <hr>
                    <button id="copy" class="copy_link"
                        data="<?php echo "http://" . $_SERVER['SERVER_NAME'].$proj_name."/exam.php?link=".$exam['link'];?>">Copy
                        Link</button>
                    <hr>
                </div>
            </div>
        </div>
    </div>
</div>
<?php } ?>

说明

  • 如果你的用户-考试分配逻辑不是用关联表实现的(例如exams表直接有assigned_user_id字段),只需调整SQL查询的过滤条件即可,核心思路是基于当前登录用户ID筛选数据。
  • 预处理语句的使用能有效防止SQL注入,提升系统安全性,这是生产环境必须做的优化。

内容的提问来源于stack exchange,提问作者John Marvin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 23:25:20