如何使用shuffle实现随机试题及在指定PHP代码中的应用位置
嘿,我来帮你搞定这两个关于随机试题实现的问题,结合你给出的PHP代码场景一步步说明:
实现随机试题功能的解决方案
问题1:如何用shuffle()实现随机试题功能
shuffle()是PHP自带的数组打乱函数,它会随机重排数组元素的顺序,刚好适配随机试题的需求。核心步骤很清晰:
- 先从数据库里把当前测试(对应
testid)下的所有试题都查出来,存成一个数组; - 用
shuffle()把这个数组的顺序彻底打乱; - 把打乱后的试题数组(或者只存试题ID的顺序)放到用户的Session里——这很重要,能保证用户在答题过程中顺序不会乱,不会每次刷新页面都重新打乱;
- 最后根据用户当前的答题进度(比如现在答到第几道),从Session的打乱数组里取对应的试题展示就行。
问题2:在你给出的PHP代码中添加shuffle()的位置及方法
你现在的代码是靠$_SESSION['qn']逐个查单道题,这种逻辑没法实现随机顺序,得调整查询方式,具体改法如下:
1. 初始化随机试题顺序(仅在用户刚进入测试时执行一次)
首先,在用户打开测试页面的初始阶段(还没开始答题的时候),先把该测试下的所有试题ID查出来,打乱后存进Session:
session_start(); if(isset($_SESSION['stdname']) && !isset($_SESSION['shuffled_questions'])) { // 查询当前测试的所有试题ID $result = executeQuery("SELECT qnid FROM question WHERE testid=" . $_SESSION['testid'] . ";"); $question_ids = []; while($r = mysql_fetch_array($result)) { $question_ids[] = $r['qnid']; } // 打乱试题ID的顺序 shuffle($question_ids); // 把打乱后的ID数组存到Session里 $_SESSION['shuffled_questions'] = $question_ids; // 初始化当前答题的索引为0(从第一题开始) $_SESSION['current_qn_index'] = 0; }
2. 修改原有代码,按打乱后的顺序取试题
接下来把你原来查单道题的逻辑换掉,改成从Session的打乱数组里取当前索引对应的试题ID:
if(isset($_SESSION['stdname'])) { // 获取当前要展示的试题ID $current_qn_id = $_SESSION['shuffled_questions'][$_SESSION['current_qn_index']]; // 查询用户的答题记录 $result = executeQuery("SELECT stdanswer, answered FROM studentquestion WHERE stdid=" . $_SESSION['stdid'] . " AND testid=" . $_SESSION['testid'] . " AND qnid=" . $current_qn_id . ";"); $r1 = mysql_fetch_array($result); // 查询当前试题的详细内容 $result = executeQuery("SELECT * FROM question WHERE testid=" . $_SESSION['testid'] . " AND qnid=" . $current_qn_id . ";"); $r = mysql_fetch_array($result); // ... 这里保留你原来处理试题展示、答题状态的代码就行 // 切换下一题的话,只需要递增current_qn_index就好(记得判断别超出数组长度) // 比如点击"下一题"按钮时可以加这段逻辑: // if($_SESSION['current_qn_index'] < count($_SESSION['shuffled_questions']) - 1) { // $_SESSION['current_qn_index']++; // } }
几个要注意的点
- 别重复打乱:一定要保证
shuffle()只在用户刚进入测试时执行一次,不然每次刷新页面都打乱,用户的答题进度直接乱套; - 保留答题进度:如果用户中途退出再进来,Session里的
shuffled_questions和current_qn_index会保留,能接着上次的位置继续答,顺序也不变; - 安全提醒:你现在的代码直接把Session变量拼进SQL里,有SQL注入的风险,建议换成预处理语句(比如用mysqli或PDO的prepare方法)来写查询,更安全。
内容的提问来源于stack exchange,提问作者Javed Ansari
相关产品推荐
相关产品推荐

