1

I'm doing a program where I have several exercises with their id (e.g. Id = 1, 2, 3 ...) What I would like to do is that once the user is in an exercise, he can press the Next button and take him to the next exercise, for example id + 1.

Below I show what I've done. Can you help me?

This is my modified question, now it works:

<?php
include_once("functions.php");

// Start the session
session_start();
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "project";

$conn = new mysqli($servername, $username, $password, $dbname);
/*echo*/ $id=$_GET['id']; // Current question
$sql = "SELECT * FROM exercises where exercise_id='$id'";
$result = $conn->query($sql); /*Check connection*/


$question_ids = [];
$result2 = doSearch($conn, 'exercise_id');
while($row = $result2->fetch_assoc()) {
    array_push($question_ids,  $row["exercise_id"]);
}
$order = $_GET['order'];
$next_question_id = -1;
$next_question_order = $order + 1;
if (count($question_ids) >= $next_question_order) {
    $next_question_id = $question_ids[$order];
}

?>

<div id="centered_B" class="header">

    <?php
    $row = $result->fetch_assoc();

    ?>

    <p><?php echo $row["exercise_id"] . ". " . $row["text"]?></p>
    <img width="603" height="auto" src="<?php echo $row["image_path"]?>"><br/><br/>

    <form action='' method='post'>
        <input type="radio" name="choice" value= "1" /><img src="<?php echo $row["image_path_A"] ?>"/><br>
        <input type="radio" name="choice" value= "2" /><img src="<?php echo $row["image_path_B"] ?>"><br>
        <input type="radio" name="choice" value= "3" /><img src="<?php echo $row["image_path_C"] ?>"><br>

    <br><br><br><!--- Select difficulty --->

    <p2>Select difficulty level:</p2>

    <form action='' method='post'>
        <select name="choose" id="choose">>
        <option value="1" <?php if($row["difficulty"]=="1") { echo "selected"; } ?> >1</option>
        <option value="2" <?php if($row["difficulty"]=="2") { echo "selected"; } ?> >2</option>
        <option value="3" <?php if($row["difficulty"]=="3") { echo "selected"; } ?> >3</option>
        <option value="4" <?php if($row["difficulty"]=="4") { echo "selected"; } ?> >4</option>
        <option value="5" <?php if($row["difficulty"]=="5") { echo "selected"; } ?> >5</option>
    </select>

    <br><br><br>


        <input class="buttonSubmit" type="submit" name="submit" value="Submit">
        <?php
        if ($next_question_id >= 0) {
        ?>
            <a href="?id=<?php echo $next_question_id; ?>&order=<?php echo $next_question_order; ?>" class="buttonNext" >Next Question</a>
        <?php
        }
        ?>

    </form>

</div><!--- end of centered_B div --->


<?php

if (isset($_POST['submit'])) {
    $user_id = $_SESSION['user_id'];
    $user_check_query = "SELECT * FROM users WHERE id='$user_id'";
    if(isset($_POST['choice'], $_POST['choose'])){
            $choice_answer=$_POST['choice'];
            $difficulty=$_POST['choose'];
//      */$user_id = $_SESSION['user_id'];*/
            $query = "INSERT INTO answers (exercise_id_fk, student_id, difficulty_student, choice_answer) VALUES ('$id','$user_id', '$difficulty', '$choice_answer')";
            $sql=mysqli_query($conn,$query);

    }
}
?>
ana
  • 417
  • 2
  • 10
  • 2
    Your script is wide open to [SQL Injection Attack](http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php) Even [if you are escaping inputs, its not safe!](http://stackoverflow.com/questions/5741187/sql-injection-that-gets-around-mysql-real-escape-string) Use [prepared parameterized statements](http://php.net/manual/en/mysqli.quickstart.prepared-statements.php) in either the `MYSQLI_` or `PDO` API's – RiggsFolly Aug 13 '18 at 13:10
  • 1
    Then I suggest you do a google on `What is SQL Injection` and read a few articles – RiggsFolly Aug 13 '18 at 13:14
  • Also you appear to be calling a js function called `getNext` but I dont see that function coded anywhere in your script – RiggsFolly Aug 13 '18 at 13:18

3 Answers3

1

Maybe this can help you:

var i=$_GET['id']){;

function getNext()
{
    var = var + 1; //increase var by one
return var;
}</script>

<button class="buttonNext" onclick="getNext" >Next Question</button>
galep
  • 80
  • 7
1

Not sure what your JS or PHP level is, but here's a pure PHP solution - not using JS.

Things to notice:

  • Using PDO parameterized queries to secure against SQL injection
  • Using a hidden form field to pass around the current question ID. After the user submits, we insert their response in the DB, and then redirect to the next question by incrementing $id++
  • You had 2 <form> tags. I removed one.

Please note, this code is not tested. Let me know if you have any questions. Good luck!

<?php
session_start();

// Using PDO instead of mysqli. Nothing wrong with mysqli but I'm more comfortable with PDO.
$host = '127.0.0.1';
$db = 'test';
$user = 'root';
$pass = '';
$charset = 'utf8mb4';

$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$opt = [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES => false,
];
// This is your connection to the DB.
$pdo = new PDO($dsn, $user, $pass, $opt);

// This is the current question being displayed to the user.
$id = $_GET['id'];

// You should probably do some validation on $id here. Should it be numeric, not null etc.

// Notice that we're using ? instead of passing the value directly to the DB. This is called prepared statements.
// https://phpdelusions.net/pdo#prepared
$stmt = $pdo->query('SELECT * FROM exercises where exercise_id = ?');
$stmt->execute([$id]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);


// You should also validate the $row here. Did you actually find a question from the DB?
?>

    <div id="centered_B" class="header">

        <p><?php echo $row["exercise_id"] . ". " . $row["text"] ?></p>
        <img width="603" height="auto" src="<?php echo $row["image_path"] ?>"><br/><br/>

        <!--        Changed the method to GET -->
        <form action="" method="GET">

            <!-- Notice that we're passing the question ID to server when the form submits. -->
            <input type="hidden" name="id" value="<?php echo $id; ?>">

            <label>
                <input type="radio" name="choice" value="1"/>
            </label><img src="<?php echo $row["image_path_A"] ?>"/><br>

            <label>
                <input type="radio" name="choice" value="2"/>
            </label><img src="<?php echo $row["image_path_B"] ?>"><br>

            <label>
                <input type="radio" name="choice" value="3"/>
            </label><img src="<?php echo $row["image_path_C"] ?>"><br>

            <br><br><br><!--- Select difficulty --->

            <p>Select difficulty level:</p>

            <label for="choose"> Difficulty
                <select name="choose" id="choose">>
                    <option value="1" <?php if ($row["difficulty"] == "1") {
                        echo "selected";
                    } ?> >1
                    </option>
                    <option value="2" <?php if ($row["difficulty"] == "2") {
                        echo "selected";
                    } ?> >2
                    </option>
                    <option value="3" <?php if ($row["difficulty"] == "3") {
                        echo "selected";
                    } ?> >3
                    </option>
                    <option value="4" <?php if ($row["difficulty"] == "4") {
                        echo "selected";
                    } ?> >4
                    </option>
                    <option value="5" <?php if ($row["difficulty"] == "5") {
                        echo "selected";
                    } ?> >5
                    </option>
                </select>
            </label>

            <br><br><br><!--- Button --->

            <!--        <button class="buttonSubmit" >Submit</button>-->
            <input type="submit" name="submit" value="Submit">
            <button class="buttonNext">Next Question</button>
        </form>

    </div><!--- end of centered_B div --->

<?php

if (isset($_POST['submit'])) {

    // Changed to a single if-statement
    if (isset($_POST['choice'], $_POST['choose'])) {

        $user_id = $_SESSION['user_id'];
        $choice_answer = $_POST['choice'];
        $difficulty = $_POST['choose'];

        // Again, using prepared statements.
        $query = "INSERT INTO answers (exercise_id_fk, student_id, difficulty_student, choice_answer) VALUES (?, ?, ?, ?)";
        $pdo
            ->prepare($query)
            ->execute([$id, $user_id, $difficulty, $choice_answer]);

        // Redirect to self with incremented question ID.
        // https://stackoverflow.com/a/8131377/296555
        header('Location: ' . $_SERVER['PHP_SELF'] . '?id=' . $id++);
        die;
    }
}
waterloomatt
  • 3,662
  • 1
  • 19
  • 25
  • Hello! my PHP or JS level is not advanced, this is my first "big" program. I'll try your code and let you know the results. :) Also im using Mysql-Workbench for storing and collecting data in the database – ana Aug 13 '18 at 14:03
  • For your question `Did you actually find a question from the DB?` Yes I did, it worked – ana Aug 13 '18 at 14:09
  • @ana - those comments are just for you to consider. You should do the validation regardless of whether your test case worked. When you put this code out into the wild, users will attempt to hit your site with `.com?id=doesntExit`, `.com?id=ev1l`, `.com?id=` etc. See here - https://stackoverflow.com/q/11418461/296555 – waterloomatt Aug 13 '18 at 14:13
  • I need time to understand your code, that's why I'm slow to answer, but I've tried it and there’s an error I don’t know why I'm getting it. This is the error: `Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000]: General error: 2031 ' and PDOException: SQLSTATE[HY000]: General error: 2031` in the line `$stmt = $pdo->query('SELECT * FROM exercises where exercise_id = ?');` – ana Aug 13 '18 at 14:41
  • Hmm. Going to be difficult for me to debug through these comments. If we're not able to figure this out shortly, let's take move this conversation to a chat. One thing to try, make sure you actually have a valid `id` in the URL. Ex. `...?id=1` Assuming `id` is a numeric field, can you please change `$id = $_GET['id'];` to `$id = (int)$_GET['id'];`? This will `cast` the value to an integer. If nothing is passed, it will be cast to `0` which the DB should be able to handle. Let me know how that goes. – waterloomatt Aug 13 '18 at 15:33
  • I managed to run the 'Next' button as I wanted, but using mysqli ... Also, users might attempt to hit my site with `.com? Id = doesntExit, .com? Id = ev1l, .com? Id = etc`, as you told me, but I dont know how to fix it. Thank you for your response and your time, I'll give it to you as valid. I'll show you how I left my code in the modified question. – ana Aug 13 '18 at 20:38
  • If you think something needs to change please tell me. – ana Aug 13 '18 at 20:47
1

Uhm, I don't know where to start here... Ok, for first your code is horrible - regarding in style, security and everything - sorry ;)

But to help with your problem: Don't access the next id directly but go by

SELECT * FROM exercises  WHERE exercise_id > $currentId ORDER BY exercise_id ASC LIMIT 0,2

This will help if you want to delete an exercise at some point, so have a gap like 1,2,4 (3 was deleted). You can also create a position field to sort the order of the question manually, but I guess that's too advanced for first.

However: On start you check if there's a $_GET['id'] param and set this to $currentId. Best by $currentId = (int)$_GET['id'] to prevent a serious injection. If no GET param is there, set $currentId = 0 (first call then). Then you run the query to get your exercise - it will be in the first row of the result.

On HTML side you just assign the exercise_id from the database result to the link which leads on the next exercise (so no JavaScript is required).

To test, if there's a next question at all check if a second row exists in the result (that's why LIMIT 0,2 instead of 0,1) to decide if to show the "next exercise button".

bibamann
  • 2,469
  • 1
  • 11
  • 9
  • Thanks for your answer biba, I managed to run the 'Next' button as I wanted, with mysqli. You can see the modified answer below. If you think something needs to change please tell me. – ana Aug 13 '18 at 20:43