仅在用户的答案正确时才增加分数

时间:2018-01-21 03:22:25

标签: php mysqli

我是一名学生,也是php的新手。我目前正在进行技能测试项目,其中计算不同类别(ABM,HUMSS,STEM,GAS,TVL)的分数。问题是即使用户的答案错误,分数仍然会增加。我希望有人可以帮我修改我的代码..

results.php

if(isset($_POST['submit'])) {
$ans = $_POST['ans'];
$abmscore = 0;
$humssscore = 0;
$stemscore = 0;
$gasscore = 0;
$tvlscore = 0;

if( !empty($ans)):
  foreach($ans as $qID => $qVal) {
  $qID =  (int) $qID;
  $qVal = (int) $qVal;

$query1= "SELECT COUNT(*) AS rightAnswer FROM tquestions WHERE test_id = $qID AND correctanswer = $qVal";
$result1= mysqli_query($conn, $query1);
$row1 = mysqli_fetch_array($result1, MYSQLI_ASSOC);

$query2 = "SELECT strand FROM tquestions WHERE test_id = $qID";
$result2 = mysqli_query($conn, $query2);
$row2 = mysqli_fetch_array($result2, MYSQLI_ASSOC); 
$strand = $row2['strand'];
if (!$result2) {
  printf("Error: %s\n", mysqli_error($conn));
  exit();
}

if($row1['rightAnswer']) {
    if($strand == 'ABM' )  {
      $abmscore++;
    }

    elseif ($strand == 'HUMSS' ) {
      $humssscore++;
    }

    elseif ($strand == 'STEM' ) {
      $stemscore++;
    }

    elseif ($strand == 'GAS' ) {
      $gasscore++;
    }

    elseif ($strand == 'TVL' ) {
      $tvlscore++;
    }      
} 

}
endif;
}

test.php的

$sql = "SELECT test_id, question, optiona, optionb, optionc, optiond FROM tquestions ORDER BY RAND() LIMIT 0, 50";      
$result = mysqli_query ($conn, $sql);
if (!$result) {
   printf("Error: %s\n", mysqli_error($conn));
exit();
}

<form action="results.php" method="POST">
        <?php if (mysqli_num_rows($result) > 0): ?>
        <?php $index = 1; $num = 1; ?>
            <?php foreach ($result as $results):
                $question = $results['question'];
                $optiona = $results['optiona'];
                $optionb = $results['optionb'];
                $optionc = $results['optionc'];
                $optiond = $results['optiond'];
                $test_id = $results['test_id'];
            ?>
                <div id="q<?php echo ($index++); ?>" class="tabcontent">
                    <table class="table table-hover">
                    <tbody>
                        <tr class="form-group">   
                            <h3 name="ques[<?php echo $test_id;?>]" style="text-indent: 40px;"> <?php echo $num,'. ', $question; ?> </h3>
                        </tr>
                        <tr class="form-group">
                            <label class="radio-inline" style="text-indent: 70px; font-size: 18px;">
                                 &nbsp;&nbsp;<input style="font-size: 18px;" type="radio" name="ans[<?php echo $test_id;?>]" value="<?php echo $optiona;?>"><?php echo $optiona;?> 
                            </label>
                            <br>
                            <label class="radio-inline" style="text-indent: 70px; font-size: 18px;">
                                 &nbsp;&nbsp;<input style="font-size: 18px;" type="radio" name="ans[<?php echo $test_id;?>]" value="<?php echo $optionb;?>"><?php echo $optionb;?> 
                            </label>
                            <br>
                            <label class="radio-inline" style="text-indent: 70px; font-size: 18px;">
                                 &nbsp;&nbsp;<input style="font-size: 18px;" type="radio" name="ans[<?php echo $test_id;?>]" value="<?php echo $optionc;?>"><?php echo $optionc;?> 
                            </label>
                            <br>
                            <label class="radio-inline" style="text-indent: 70px; font-size: 18px;">
                                 &nbsp;&nbsp;<input style="font-size: 18px;" type="radio" name="ans[<?php echo $test_id;?>]" value="<?php echo $optiond;?>"><?php echo $optiond;?>
                            </label>
                            <br>
                        </tr>
                    </tbody>
                    </table>
                </div>                    
            <?php $num++; ?>
            <?php endforeach ?>
        <?php endif ?>

        <br>

        <div class="form-group"><center>
            <input class="btn btn-success" type="submit" name="submit" value="Submit" onclick="return confirm('Are you sure you want to submit your answers?')"></center>
        </div>

以下是我的测试问题数据库表:

testquestions table

2 个答案:

答案 0 :(得分:1)

这里有很多包装,我测试过它是成功的,但是如果有人发现了一个缺陷,请告诉我,我会解决它。

这是我正在使用的数据库表数据:http://sqlfiddle.com/#!9/036c06/1/0

这是我的test.php代码:

if (!$conn=new mysqli($host,$user,$pass,$db)) {
    echo "Database Connection Error: " , $conn->connect_error;  // don't show error messages to the public
} elseif (!$result = $conn->query('SELECT test_id, question, optiona, optionb, optionc, optiond FROM tquestions ORDER BY RAND() LIMIT 50')) {
    echo "Syntax Error: " , $conn->error;  // don't show error messages to the public
} elseif (!$result->num_rows) {
    echo "Logic Error: No Rows @ Questions Query";
} else {
    echo "<form action=\"results.php\" method=\"POST\">";
        $i = 0;
        while ($row=$result->fetch_assoc()) {
            echo "<div id=\"q",++$index,"\" class=\"tabcontent\">";
                echo "<table class=\"table table-hover\">";
                    echo "<tbody>";
                        echo "<tr class=\"form-group\">";
                            echo "<h3 name=\"ques{$row['test_id']}\" style=\"text-indent:40px;\"> " , ++$i , ". {$row['question']} </h3>"; // can't see a reason to have a name attribute here
                        echo "</tr>";
                        $options = [$row['optiona'],$row['optionb'],$row['optionc'],$row['optiond']];
                        shuffle($options);  // shuffle the options to improve test structure
                        echo "<tr class=\"form-group\">";
                            foreach ($options as $option) {
                                echo "<label class=\"radio-inline\" style=\"text-indent:70px;font-size:18px;\">&nbsp;&nbsp;";
                                    echo "<input style=\"font-size:18px;\" type=\"radio\" name=\"ans[{$row['test_id']}]\" value=\"$option\">$option";
                                echo "</label><br>";
                            }
                        echo "</tr>";
                    echo "</tbody>";
                echo "</table>";
            echo "</div>";
        }
        echo "<div class=\"form-group\">";
            echo "<center><input class=\"btn btn-success\" type=\"submit\" name=\"submit\" value=\"Submit\" onclick=\"return confirm('Are you sure you want to submit your answers?')\"></center>";
        echo "</div>";
    echo "</form>";
}

一些注意事项:

  • 我不喜欢进出php,所以我只是留在php里面并回应所有内容(个人喜好)。
  • 我选择使用面向对象的mysqli语法(个人偏好)。
  • 我删除了name代码上的<h3>属性,因为我没有看到好处。如果您有理由,只需重新添加即可。
  • 我已经改变了每个问题的选项,以便每次测试都显得“新鲜”。
  • 我在循环中显示了选项,使代码更加干燥。

这是我的results.php代码:

if (!isset($_POST['submit']) && !empty($_POST['ans'])) {
    echo "Insufficient Submission Data Received";
} elseif (!$conn=new mysqli($host,$user,$pass,$db)) {
    echo "Database Connection Error: ",$conn->connect_error;
} else {
    $params = array_keys($_POST['ans']);  // collect test_ids from submission data
    $results = array('ABM'=>0,'HUMSS'=>0,'STEM'=>0,'GAS'=>0,'TVL'=>0);  // init / zero-out the categories

    $count = count($params);  // number of fullstring matches
    $csph = implode(',',array_fill(0,$count,'?'));  // comma-separated placeholders

    if (!$stmt=$conn->prepare("SELECT test_id,strand,correctanswer FROM tquestions WHERE test_id IN ($csph);")) {
        echo "Syntax Error @ prepare: " , $conn->error;  // don't show error messages to the public
    } else {
        array_unshift($params, str_repeat('s', $count));  // prepend the type values string
        $ref = [];  // add references
        foreach ($params as $i=>$v) {
            $ref[$i] = &$params[$i];  // pass by reference as required/advised by the manual
        }
        call_user_func_array([$stmt, 'bind_param'], $ref);    

        if (!$stmt->execute()) {
            echo "Error @ bind_param/execute: ",$conn->error;
        } elseif (!$stmt->bind_result($test_id,$strand,$correctanswer)) {
            echo "Error @ bind_result: " , $stmt->error;  // don't show error messages to the public
        } else {
            while ($stmt->fetch()) {
                if (isset($_POST['ans'][$test_id], $results[$strand]) && $_POST['ans'][$test_id] == $correctanswer) {
                    ++$results[$strand];
                }
            }
            $stmt->close();
            var_export($results);
        }
    }
}

一些注意事项:

  • 我只是在脚本开头做一些基本的提交检查。如果您愿意,可以进行其他改进。
  • 作为数据库保护的问题,我使用预准备语句使用用户提供的数据查询数据库。不幸的是,生成“安全”IN子句的过程相当冗长。如果您刚刚开始使用php,那么您不需要“理解”call_user_func_array()所涉及的所有组件。你现在可能只是相信它,并且当你想要围绕它时,可以稍后研究它。
  • 我决定将分类正确的答案存储为数据数组,而不是单个变量,因为它是一组具有相同统一结构的数据。
  • 如果您想知道我的脚本中分配给特定值的数据,只需在变量上写一些策略性的echovar_export()

当我向result.php提交“完美”表格时,这是$_POST数据:

array ( 1 => '1 and 0', 8 => 'Marcelo del Pilar', 7 => 'Marcelo del Pilar', 3 => 'Liability', 5 => 'Variable', 4 => 'Crisis', 6 => 'Marcelo del Pilar', )

这是$results数据:

array ( 'ABM' => 1, 'HUMSS' => 1, 'STEM' => 1, 'GAS' => 3, 'TVL' => 1, )

答案 1 :(得分:0)

编辑:

好的,之后可能需要一些解释,但我相信我找到了适合你的解决方案。您现在拥有的代码为您的所有无线电选项提供了相同的名称:ans<?php echo $test_id ?>。通过这样做,您将所有4个选项一次传递给同一个变量。这是一个问题。

将输入的名称更改为唯一,并在隐藏的输入中将test_id传递给results.php:

<tr class="form-group">
  <input type="hidden" name="test_id" value="<?php echo $test_id ?>">
<label class="radio-inline" style="text-indent: 70px; font-size: 18px;">
  <input style="font-size: 18px;" type="radio" name="option_a" value="<?php echo $optiona;?>"><?php echo $optiona;?> 
</label>
<br>
<label class="radio-inline" style="text-indent: 70px; font-size: 18px;">
  <input style="font-size: 18px;" type="radio" name="option_b" value="<?php echo $optionb;?>"><?php echo $optionb;?> 
</label>
<br>
<label class="radio-inline" style="text-indent: 70px; font-size: 18px;">
  <input style="font-size: 18px;" type="radio" name="option_c" value="<?php echo $optionc;?>"><?php echo $optionc;?> 
</label>
<br>
<label class="radio-inline" style="text-indent: 70px; font-size: 18px;">
  <input style="font-size: 18px;" type="radio" name="option_d" value="<?php echo $optiond;?>"><?php echo $optiond;?>
</label>
<br>
</tr>

然后更新你的test.php,比如选中WHICH radio,并从那个隐藏的字段中获取test_id:

if(isset($_POST['submit'])) {
    if (isset($_POST['option_a'])) $ans = $_POST['option_a'];
    if (isset($_POST['option_b'])) $ans = $_POST['option_b'];
    if (isset($_POST['option_c'])) $ans = $_POST['option_c'];
    if (isset($_POST['option_d'])) $ans = $_POST['option_d'];
    if (isset($_POST['test_id'])) $id = $_POST['test_id'];

然后删除你的foreach循环并将你的SQL查询修复为“SELECT correctanswer FROM tquestions WHERE test_id = $ id”,因为我们拥有所有其他信息,我们只需要根据我们传递的问题的ID得到正确的答案来自test.php

$query1= "SELECT correctanswer AS rightAnswer FROM tquestions WHERE test_id = $id";

最后,results.php应如下所示:

if(isset($_POST['submit'])) {
    if (isset($_POST['option_a']) $ans = $_POST['option_a'];
    if (isset($_POST['option_b']) $ans = $_POST['option_b'];
    if (isset($_POST['option_c']) $ans = $_POST['option_c'];
    if (isset($_POST['option_d']) $ans = $_POST['option_d'];
    if (isset($_POST['test_id'])) $id = $_POST['test_id'];
    $abmscore = 0;
    $humssscore = 0;
    $stemscore = 0;
    $gasscore = 0;
    $tvlscore = 0;

    $query1= "SELECT correctanswer AS rightAnswer FROM tquestions WHERE test_id = $id";
    $result1= mysqli_query($conn, $query1);
    $row1 = mysqli_fetch_array($result1, MYSQLI_ASSOC);

    $query2 = "SELECT strand FROM tquestions WHERE test_id = $id";
    $result2 = mysqli_query($conn, $query2);
    $row2 = mysqli_fetch_array($result2, MYSQLI_ASSOC);
    $strand = $row2['strand'];
    if (!$result2) {
        printf("Error: %s\n", mysqli_error($conn));
        exit();
    }

    if($ans == $row1['rightAnswer']) {
        if($strand == 'ABM')  {
          $abmscore++;
        }
        elseif ($strand == 'HUMSS') {
          $humssscore++;
        }
        elseif ($strand == 'STEM') {
          $stemscore++;
        }
        elseif ($strand == 'GAS') {
          $gasscore++;
        }
        elseif ($strand == 'TVL') {
          $tvlscore++;
        }
    }
}

你的test.php中有一些不必要的东西。您不需要为每行PHP代码使用。您只需打开它并在解析其他语言(如HTML)之间关闭它。如果你想让我进一步解释,我会很高兴,但就目前而言,我已经调整了test.php:

$sql = "SELECT test_id, question, optiona, optionb, optionc, optiond FROM tquestions ORDER BY RAND() LIMIT 0, 50";      
$result = mysqli_query ($conn, $sql);
if (!$result) {
   printf("Error: %s\n", mysqli_error($conn));
exit();
}

<form action="results.php" method="POST">
    <?php if (!mysqli_num_rows($result) > 0) die('No data');
    foreach ($result as $results) {
        $question = $results['question'];
        $optiona = $results['optiona'];
        $optionb = $results['optionb'];
        $optionc = $results['optionc'];
        $optiond = $results['optiond'];
        $test_id = $results['test_id'];
        } ?>
        <div id="q<?php echo ($index++); ?>" class="tabcontent">
            <table class="table table-hover">
            <tbody>
            <tr class="form-group">   
                <h3 name="ques[<?php echo $test_id;?>]" style="text-indent: 40px;"> <?php echo $num,'. ', $question; ?> </h3>
            </tr>
            <tr class="form-group">
                <label class="radio-inline" style="text-indent: 70px; font-size: 18px;">
                 &nbsp;&nbsp;<input style="font-size: 18px;" type="radio" name="ans[<?php echo $test_id;?>]" value="<?php echo $optiona;?>"><?php echo $optiona;?> 
                </label>
                <br>
                <label class="radio-inline" style="text-indent: 70px; font-size: 18px;">
                 &nbsp;&nbsp;<input style="font-size: 18px;" type="radio" name="ans[<?php echo $test_id;?>]" value="<?php echo $optionb;?>"><?php echo $optionb;?> 
                </label>
                <br>
                <label class="radio-inline" style="text-indent: 70px; font-size: 18px;">
                 &nbsp;&nbsp;<input style="font-size: 18px;" type="radio" name="ans[<?php echo $test_id;?>]" value="<?php echo $optionc;?>"><?php echo $optionc;?> 
                </label>
                <br>
                <label class="radio-inline" style="text-indent: 70px; font-size: 18px;">
                 &nbsp;&nbsp;<input style="font-size: 18px;" type="radio" name="ans[<?php echo $test_id;?>]" value="<?php echo $optiond;?>"><?php echo $optiond;?>
                </label>
                <br>
            </tr>
            </tbody>
            </table>
        </div>
    <br>

    <div class="form-group"><center>
        <input class="btn btn-success" type="submit" name="submit" value="Submit" onclick="return confirm('Are you sure you want to submit your answers?')"></center>
    </div>  

为了我的缘故,我希望这对你有用。