PHP for循环中array_rand仅返回首个数组元素值的问题排查
问题相关代码
include '../db.php'; $sql = "SELECT question, rightans, ans2, ans3, ans4, id, subject, author FROM others WHERE subject = '".$sub."'"; $result = $con->query($sql); $question=array(); if ($result->num_rows > 0) { $x=0; while($row = $result->fetch_assoc()) { if ($row['question']!=""){ $question[$x]=$row['question']; $x=$x+1; } }} $random_keys=array_rand($question,20); $rd=count($random_keys); $con->close(); $z=array(); for ($y = 0; $y <= $rd; $y++) { echo $question[$random_keys[$y]]; }
问题描述
编写上述PHP代码,从数据库others表中读取指定科目下的非空题目存入$question数组,调用array_rand()方法抽取20个随机元素的键名,再通过for循环遍历输出对应题目。按照逻辑本应得到20道随机题目,但实际运行时仅输出第一道题目。
初步排查发现:循环变量$y可正常递增,手动访问$question[$random_keys[1]]、$question[$random_keys[2]]均能返回预期的对应值,但使用循环变量$y作为索引访问$question[$random_keys[$y]]时,始终仅返回$question[$random_keys[0]]对应的内容。
问题原因
- 核心显示异常原因:PHP循环逻辑本身没有问题,所有题目已经被正常输出,异常出在前端渲染环节。从数据库读取的题目文本包含未闭合的HTML语法片段(比如未终止的注释
<!--、未闭合的<textarea>/<div>等标签、带隐藏样式的未闭合标签),浏览器解析HTML时会把第一题之后的所有内容识别为标签属性或隐藏内容,导致页面视觉上只显示第一道题。右键查看网页源代码即可看到所有题目都已正常返回。 - 代码边界bug:for循环的终止条件写错。
array_rand($question,20)返回的数组长度为20,数字索引范围是0~19,现有条件$y <= $rd会让循环执行21次,最后一次$y=20属于越界访问不存在的数组索引,会触发Notice级错误,输出空值。
修复方案
- 修正循环终止条件,将
$y <= $rd改为$y < $rd,避免越界访问。 - 输出题目时使用
htmlspecialchars()对内容做HTML转义,既可以避免未闭合标签打乱页面渲染,也能防范XSS风险,同时可以在每道题后加换行标签分隔内容:
for ($y = 0; $y < $rd; $y++) { echo htmlspecialchars($question[$random_keys[$y]]) . "<br>"; }
- 如果是在CLI命令行环境运行脚本出现该问题,检查题目文本是否包含
\r回车符,这类字符会让终端光标回到行首,后续输出内容会覆盖当前行内容,造成只显示单题的错觉,使用htmlspecialchars()转义特殊字符即可解决。
内容的提问来源于stack exchange,提问作者Suprin Aziz Talpur
相关产品推荐
相关产品推荐

