PHP实现随机获取题目及答题记录接口
本文介绍了如何使用 PHP 和 MySQL 构建一个简单的答题应用后端接口,核心逻辑涵盖 Session 校验、剩余次数管理、随机选题及数据回传。
实现思路与目标
该接口旨在为前端提供一次完整的答题请求服务。当用户点击“开始答题”时,服务端需完成以下任务:
- 确认当前会话有效且未超时。
- 扣除用户的当日可用答题次数。
- 从题库中不重复地随机选取 5 道题目。
- 将选出的题目内容(题干及选项)以 JSON 格式返回。
- 在后台记录本次生成的 5 道题目的 ID,为后续接收答案并判分做准备。
准备条件
实现该功能需要确保环境满足以下条件:
- 数据库连接:项目中存在可靠的
connect_database.php文件,使用$mysqli对象连接数据库。 - 数据结构:
- 用户表
zaszh_user:包含id和answer_surplus(剩余答题次数)字段。 - 题目表
zaszh_question:包含id、question(题干)、A-D(四个选项)及answer(正确答案)字段。 - 记录表
zaszh_answer:用于存储每次产生的题目序列,包含user_id、question1-question5及时间戳。
- 用户表
- PHP 版本:支持 MySQLi 扩展的 PHP 环境(推荐开启短标签或避免使用,代码中采用标准写法)。
真实操作顺序
第1步:初始化与会话校验
首先设置 Session 缓存过期时间并开始 Session 会话。随后检查全局变量 $_SESSION 中是否存在标识用户身份的 zaszh_user_id。若不存在,说明连接可能已过期或非法请求,直接返回错误 JSON 并终止脚本。
第2步:生成不重复的随机题号
为了每次呈现不同的题目,需要从指定范围(例如 1 到 114)内随机生成 5 个不重复的数字。代码中使用 while 循环配合 in_array() 函数进行查重,直到数组长度达到 5 为止,最终得到 $question_id 数组。
第3步:更新剩余答题次数
通过 UPDATE SQL 语句尝试将对应用户的 answer_surplus 减 1。执行后检查 $mysqli->affected_rows 的值。如果受影响行数为 0,说明用户无剩余次数或 ID 无效,此时应返回提示“今日答题剩余次数已用完”,关闭连接并退出,防止资源浪费。
第4步:预处理查询题目详情
直接使用字符串拼接查询存在注入风险。本例使用 $mysqli->prepare() 创建预处理语句:
select question,A,B,C,D,answer from zaszh_question where id in(?,?,?,?,?)。
使用 bind_param('iiiii', ...) 绑定刚才生成的 5 个随机 ID,并通过 fetch() 循环遍历结果集,将每道题的数据组装成关联数组存入 $rows。
第5步:记录本次题目序列并返回结果
为了确保后续能知道这次发给用户的是哪套题,需要将这 5 个 ID 存入 zaszh_answer 表。同样使用预处理语句插入:
insert into zaszh_answer(user_id,question1,question2,question3,question4,question5,create_date) values(?,?,?,?,?,?,unix_timestamp(now()))。
若插入成功,获取生成的主键 ID answer_id,并将其与题目列表合并,最终通过 json_encode() 输出给前端。若数据库发生错误,则返回“系统出错”提示。
<?php
session_cache_expire(60);
session_start();
// 1. 校验登录状态
if(!isset($_SESSION['zaszh_user_id'])) {
echo json_encode(array('status'=>'error','msg'=>'连接超时,请重新打开页面。'));
exit;
}
$user_id = $_SESSION['zaszh_user_id'];
// 2. 随机获取5道不重复的问题ID (假设题库ID范围是1-114)
$question_id = array();
while(sizeof($question_id) < 5) {
$num_rand = mt_rand(1, 114);
if(!in_array($num_rand, $question_id))
$question_id[] = $num_rand;
}
require('connect_database.php'); // 引入数据库连接配置
// 3. 扣减答题次数
$mysqli->query("update zaszh_user set answer_surplus=answer_surplus-1 where id={$user_id} and answer_surplus>0");
if($mysqli->affected_rows == 0) {
echo json_encode(array('status'=>'error','msg'=>'今日答题剩余次数已用完,明天再来哦~'));
$mysqli->close();
exit;
}
$rows = array();
$stmt = null;
// 4. 安全获取题目数据
if($stmt = $mysqli->prepare("select question,A,B,C,D,answer from zaszh_question where id in(?,?,?,?,?)")) {
$stmt->bind_param('iiiii', $question_id[0], $question_id[1], $question_id[2], $question_id[3], $question_id[4]);
$stmt->execute();
$stmt->bind_result($question, $A, $B, $C, $D, $answer);
while($stmt->fetch()) {
$rows[] = array(
'question'=>$question,
'A'=>$A, 'B'=>$B, 'C'=>$C, 'D'=>$D,
'answer'=>$answer
);
}
// 5. 记录本次题目ID以便后续核对答案
if($stmt2 = $mysqli->prepare("insert into zaszh_answer(user_id,question1,question2,question3,question4,question5,create_date) values(?,?,?,?,?, ?,unix_timestamp(now()))")) {
$stmt2->bind_param('iiiiii', $user_id, $question_id[0], $question_id[1], $question_id[2], $question_id[3], $question_id[4]);
$stmt2->execute();
$answer_id = $stmt2->insert_id;
}
$stmt->close();
}
// 输出最终结果
if(isset($answer_id) && $answer_id > 0) {
echo json_encode(array_merge($rows, array('answer_id'=>$answer_id)));免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









