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

PHP技能测试项目分数计算问题求助:仅正确作答时加分

问题分析与修复方案

看起来你遇到的核心问题是错误答案也会触发分数累加,这大概率是因为答案判断逻辑的漏洞加上潜在的SQL语法/类型问题导致的。咱们一步步拆解修复:

主要问题点

  1. 不必要的类型转换破坏答案匹配:你把用户提交的选项值$qVal强制转成了int,如果数据库里的correctanswer是字符串类型(比如选项文本、A/B/C/D这类标识),转换后会直接变成0,导致正确答案永远匹配失败,反而可能因为SQL逻辑的异常触发错误加分。
  2. SQL注入风险+查询效率低:直接把用户输入拼进SQL语句,不仅有安全风险,还分开执行了两次查询(查正确答案、查 strand),完全可以合并成一次。
  3. 缺失查询错误处理:只处理了$result2的错误,没处理$result1的,万一查正确答案的SQL出错,后续逻辑会乱。
  4. 模糊的正确判断:用if($row1['rightAnswer'])虽然能判断非0值,但不如明确判断=== 1严谨,避免意外情况。

修复后的results.php代码

<?php
if(isset($_POST['submit'])) {
    $ans = $_POST['ans'] ?? []; // 确保数组存在,避免未定义索引警告
    $abmscore = 0;
    $humssscore = 0;
    $stemscore = 0;
    $gasscore = 0;
    $tvlscore = 0;

    if(!empty($ans)):
        // 预处理语句,合并查询,防止SQL注入,提高效率
        $stmt = mysqli_prepare($conn, "SELECT correctanswer, strand FROM tquestions WHERE test_id = ?");
        mysqli_stmt_bind_param($stmt, "i", $qID); // test_id是整数,用i类型绑定

        foreach($ans as $qID => $qVal) {
            $qID = (int) $qID; // test_id是整数,转换没问题
            // 注意:这里不要转$qVal类型,保留原始提交值,和数据库correctanswer类型匹配
            
            // 执行查询获取当前问题的正确答案和所属strand
            mysqli_stmt_execute($stmt);
            $result = mysqli_stmt_get_result($stmt);
            if(!$result) {
                printf("Error: %s<br>", mysqli_error($conn));
                exit();
            }
            $row = mysqli_fetch_array($result, MYSQLI_ASSOC);
            if(!$row) {
                // 找不到对应test_id的问题,跳过
                continue;
            }

            // 判断用户答案是否正确
            if($qVal === $row['correctanswer']) {
                // 根据strand累加分数
                switch($row['strand']) {
                    case 'ABM':
                        $abmscore++;
                        break;
                    case 'HUMSS':
                        $humssscore++;
                        break;
                    case 'STEM':
                        $stemscore++;
                        break;
                    case 'GAS':
                        $gasscore++;
                        break;
                    case 'TVL':
                        $tvlscore++;
                        break;
                }
            }
        }
        mysqli_stmt_close($stmt);
    endif;
}
?>

额外需要检查的点

  1. test.php的选项值匹配:确保你在test.php中输出的radio按钮value和数据库correctanswer字段的内容完全一致。比如:

    • 如果数据库correctanswer存的是选项标识(如'A'/'B'),那test.php里的value应该输出标识,而不是选项文本:
      // 假设数据库里有对应选项标识的字段,比如correctanswer='A'
      <input type="radio" name="ans[<?php echo $test_id;?>]" value="A"><?php echo $optiona;?>
      
    • 如果存的是选项文本,那当前的value写法没问题,但要确保文本完全一致(包括空格、大小写)。
  2. 数据库字段类型:确认tquestions表的correctanswer字段类型和用户提交的value类型匹配,比如都是VARCHAR或都是INT,避免类型不匹配导致的判断失败。

为什么这样修复?

  • 用预处理语句彻底解决SQL注入问题,同时避免手动拼接SQL的语法错误。
  • 合并两次查询为一次,减少数据库交互,提升性能。
  • 去掉了破坏答案匹配的$qVal = (int) $qVal,保留原始提交值和数据库直接比对。
  • 用switch替代多个elseif,代码更简洁易维护。
  • 增加了对找不到问题的处理,避免无意义的逻辑执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:49:45