Kuis Sederhana Bagian 2 | Menyimpan Hasil dan Jawaban ke Database

Pada tutorial sebelumnya Membuat Kuis Sederhana Dengan PHP kita telah belajar untuk menampilkan pertanyaan dan jawaban secara acak dan juga menampilkan hasil kuis. Tetapi tidak hasil dan jawaban tidak disimpan ke database. Tutorial ini akan menjelaskan cara untuk menyimpan hasil dan jawaban pengguna dan kemudian menampilkannya. Dalam tutorial ini kita akan menggunakan database transaction untuk menjamin semua data tersimpan. Tutorial membuat kuis sederhana juga dilengkapi dengan video tutorial yang bisa ditonton lewat Youtube channel MyPHPtutorials.

Video Tutorial Menyimpan Jawaban dan Hasil Ke Database

Video Tutorial Menyimpan Jawaban dan Hasil Ke Database

Membuat Form Login

Sebelum bisa menyimpan hasil kita perlu mengetahui informasi pengguna yang menjawah kuis. Oleh sebab itu kita perlu membuat form login dulu. Sudah ada beberapa tutorial untuk membuat form login seperti Studi kasus Forum : Form Login User & Log out Sistem atau Membuat Form Login Yang Lebih Aman. Pada tutorial ini kita akan membuat yang sederhana sebagai materi pendukung. Buatlah tabel users seperti di bawah.

Kolom Tipe data Keterangan
id integer primary key, auto increment
nama varchar(255)
email varchar(255)
password varchar(255)

kemudian tambahkan gunakan sql query di bawah untuk menambahkan pengguna

insert into users (name, email, password) values ('Joni', 'joni@example.com', sha1('change_me'));

Kemudian buatlah file login.php untuk seperti di bawah

<?php
session_start();
$error = '';
if (!empty($_POST)) {
    $pdo = require 'koneksi.php';
    $query = $pdo->prepare("SELECT * FROM users WHERE email=:email");
    $query->execute(array('email' => $_POST['email']));
    $user = $query->fetch();
    if (!$user) {
        $error = 'Email atau password salah';
    } elseif (sha1($_POST['password']) == $user['password']) {
        $_SESSION['user'] = array(
            'id' => $user['id'],
            'nama' => $user['name']
        );
        header("Location: index.php");
        exit;
    } else {
        $error = 'Email atau password salah';
    }
}
?>
<!DOCTYPE html>
<html>
    <head>
        <title>Login</title>
    </head>
    <body>
        <h1>Silahkan Login</h1>
        <?php
        if ($error) {
            echo '<p styles="color:red">'.$error.'</p>';
        }
        ?>
        <form action="" method="POST">
            <p>
                <label>Email</label>
                <p>
                    <input type="email" name="email" required/>
                </p>
            </p>
            <p>
                <label>Password</label>
                <p>
                    <input type="password" name="password" required/>
                </p>
            </p>
            <p>
                <button type="submit">Login</button>
            </p>
        </form>
    </body>
</html>

Kemudian buat file cek-akses.php untuk digunakan melakukan pengecekan apakah user sudah login atau belum, jika belum gunakan arahkan pengguna ke halaman login.

<?php
session_start();
if (!isset($_SESSION['user']) || empty($_SESSION['user'])) {
    header("Location: login.php");
}

Kemudian require file ini ke semua file selain login.php seperti:

<?php
require_once 'cek-akses.php';
?>

Membuat Tabel Hasil Kuis

Ada dua tabel yang perlu dibuat, pertama tabel hasil seperti di bawah:

Kolom Tipe data Keterangan
id integer primary key, auto increment
id_user int foreign key ke kolom id table users
tanggal datetime untuk mencatat tanggal menjawab
nilai int

Kemudian membuat tabel untuk mencatat masing jawaban user, yaitu table hasil_jawaban

Kolom Tipe data Keterangan
id integer primary key, auto increment
id_hasil int foreign key ke kolom id table hasil
id_jawaban int foreign key ke kolom id table jawaban
bener tinyint 1 kalau benar dan 0 kalau salah
skor int

Menyimpan Hasil Kuis

Untuk menyimpan hasil buatlah file jawab.php yang akan menerima jawab user menyimpan hasilnya kemudian mengarahkan user ke halaman hasil.

<?php
require_once 'cek-akses.php';
if (empty($_POST['jawaban']) === false) {
    $pdo = include "koneksi.php";
    $totalSkor = 0;
    try {
        $pdo->beginTransaction();
        $queryHasil = $pdo->prepare("INSERT INTO hasil (id_user, tanggal, nilai)
        VALUES (:id_user, now(), 0)");
        $queryHasil->execute(array('id_user' => $_SESSION['user']['id']));
        $idHasil = $pdo->lastInsertId();
        foreach ($_POST['jawaban'] as $idPertanyaan => $idJawaban) {
            // Query pertanyaan
            $query = $pdo->prepare("select * from pertanyaan where id = :id");
            $query->execute(array("id" => $idPertanyaan));
            $pertanyaan = $query->fetch();
            // Query jawaban
            $query2 = $pdo->prepare("select * from jawaban where id = :id and id_pertanyaan = :id_pertanyaan");
            $query2->execute(array(
                'id' => $idJawaban,
                'id_pertanyaan' => $idPertanyaan
            ));
            $jawaban = $query2->fetch();
            $benar = 0;
            $isJawaban = null;
            if ($jawaban) {
                $idJawaban = $jawaban['id'];
                if ($jawaban['benar'] == 1) {
                    $totalSkor += $pertanyaan['skor'];
                    $benar = 1;
                }
            }

            $queryHasilJawaban = $pdo->prepare("INSERT INTO hasil_jawaban 
            (id_hasil, id_jawaban, benar, skor)
            VALUES (:id_hasil, :id_jawaban, :benar, :skor)");
            $queryHasilJawaban->execute(array(
                'id_hasil' => $idHasil,
                'id_jawaban' => $idJawaban,
                'benar' => $benar,
                'skor' => $pertanyaan['skor']
            ));
        }

        $queryUpdateSkor = $pdo->prepare("UPDATE hasil SET nilai=:nilai WHERE id=:id");
        $queryUpdateSkor->execute(array(
            'nilai' => $totalSkor,
            'id' => $idHasil
        ));
        $pdo->commit();
        header("Location: hasil.php?id=".$idHasil);
    } catch (Exception $e) {
        $pdo->rollBack();
        echo $e->getMessage();
    }
}

Pada baris ke-4 kita membuat koneksi ke database, kemudian baris ke-6 kita membuat try dan catch blok yang tujuannya adalah untuk me-rollback transaksi database jika terjadi kesalahan atau kegagalan saat menyimpan data salah satu jawaban pengguna. Di baris ke-7 kita menggunakan fungsi PDO::beginTransaction untuk memulai transaksi, artinya data tersimpan sementara dan bisa dikembalikan ke kondisi awal kalau terjadi kesalahan. Dari baris 8 ke 10 kita menyimpan data hasil menggunakan SQL insert tapi nilai diset 0 terlebih dahulu. Di baris ke-12 kita mulai melakukan iterasi untuk menyimpan setiap jawaban dari setiap pertanyaan. Di baris ke-34 sampai 42 kita kemudian menyimpan data jawaban pengguna. Kemudian setelah iterasi di baris 45 - 49 kita mengupdate nilai dari pengguna. Di baris ke-50 kita membuat menggunakan fungsi PDO::commit untuk mengakhiri transaksi database dan benar benar menyimpan data ke database. Di baris selanjutnya kita mengarahkan user ke halaman hasil.

Menampilkan Hasil Kuis

Selanjut adalah kita perlu mengubah file index.php dan mengubah action dari form menjadi jawab.php. File hasil.php sebelumnya yang kita buat dari tutorial kuis sebelumnya perlu kita ubah untuk menampilkan hasil langsung dari database seperti di bawah:

<?php
require_once 'cek-akses.php';
?>
<!DOCTYPE html>
<html>
    <head>
        <title>Hasil Kuis</title>
    </head>
    <body>
        <h1>Hasil Kuis Anda</h1>
        <?php
        $pdo = include "koneksi.php";
        if (isset($_GET['id']) && !empty($_GET['id'])) {
            $query = $pdo->prepare("SELECT * FROM hasil where id=:id");
            $query->execute(array('id' => $_GET['id']));
            $hasil = $query->fetch();
            if (!$hasil) {
                echo '<p>Hasil tidak ditemukan</p>';
            } else {
                // Tampilkan Skor
                echo '<h1>Selamat Skor Anda: '.$hasil['nilai'].'</h1>';
                echo '<h2>Detil Hasil Anda</h2>';
                echo '<ol>';
                $query2 = $pdo->prepare("SELECT hasil_jawaban.*, jawaban.deskripsi as jawab, pertanyaan.deskripsi as tanya
                FROM hasil_jawaban
                INNER JOIN jawaban ON jawaban.id=hasil_jawaban.id_jawaban
                INNER JOIN pertanyaan ON jawaban.id_pertanyaan=pertanyaan.id 
                WHERE id_hasil=:id_hasil");
                $query2->execute(array(
                    'id_hasil' => $hasil['id']
                ));
                while($data = $query2->fetch()) {
                    echo '<li>';
                    echo htmlentities($data['tanya']);
                    echo '<p>Jawaban: '. htmlentities($data['jawab']).'</p>';
                    if ($data['benar'] == 1) {
                        echo '<p style="color:green">Benar</p>';
                    } else {
                        echo '<p style="color:red">Salah</p>';
                    }
                    echo '</li>';
                }
                echo '</ol>';
            }
        }
        ?>
    </body>
</html>

Di baris ke-13 kita mulai melakukan pengecekan apakah ada parameter id yang kirim oleh file jawab.php, jika ada maka kita melakukan query hasil di baris 14 - 16. Jika hasil ditemukan maka tampilkan jawaban setiap pertanyaan seperti sebelumnya, tapi kali ini menggunakan query join untuk menampilkan data dari tabel jawaban, pertanyaan dan juga hasil, seperti di baris 24 - 28. Bagi yang ingin belajar lebih lanjut tentang query join bisa kunjungi tutorial 9 Dasar SQL Query Paling Umum dan Wajib Diketahui Programmer. Kemudian di baris ke-33 sampai 42 kita menampilkan hasil jawaban, kita benar ditampilkan tulisan benar berwana hijau, sebaliknya tampilkan tulisan salah merah.

Kesimpulan

Dalam tutorial ini dijelaskan cara untuk menyimpan hasil dan jawaban kuis ke database. Juga menampilkan hasilnya menggunakan SQL Query Join untuk menampilkan 3 tabel sekaligus. Contoh kode bisa didownload di sini. Selamat Mencoba.