Materi
Dapur Bu Ratna di Semarang menerima pesanan katering lewat formulir. Program di bawah membaca nama dan jumlah porsi dari $_POST, menolak pesanan di bawah 10 porsi, memberi harga Rp23.000 per porsi untuk 50 porsi ke atas dan Rp25.000 untuk sisanya, menyimpan pesanan ke basis data dengan prepared statement, lalu menghitung jumlah pesanan tersimpan. Basis datanya SQLite di memori, jadi setiap permintaan mulai dari tabel kosong.
Setiap soal menyebut isian formulir yang dikirim. Telusuri dari baris $_POST: apa hasil cast (int), apakah hitungTotal melempar exception, dan bila ya, baris mana yang dilewati. Ingat bahwa htmlspecialchars hanya mengubah teks yang DICETAK, bukan isi variabelnya. Isi basis data tetap asli; pengamanan untuk HTML dilakukan di setiap tempat data itu dicetak.
<?php
// pesan.php — formulir pesanan katering Dapur Bu Ratna, Semarang
$db = new PDO("sqlite::memory:");
$db->exec("CREATE TABLE pesanan (nama TEXT, porsi INTEGER, total INTEGER)");
function hitungTotal(int $porsi): int {
if ($porsi < 10) {
throw new InvalidArgumentException("Minimal pesan 10 porsi");
}
$harga = match (true) {
$porsi >= 50 => 23000,
default => 25000,
};
return $porsi * $harga;
}
$nama = $_POST["nama"] ?? "";
$porsi = (int) ($_POST["porsi"] ?? 0);
try {
$total = hitungTotal($porsi);
$s = $db->prepare("INSERT INTO pesanan VALUES (?, ?, ?)");
$s->execute([$nama, $porsi, $total]);
echo "<p>Pesanan " . htmlspecialchars($nama) . " tersimpan.</p>\n";
echo "<p>Total: Rp" . number_format($total, 0, ',', '.') . "</p>\n";
} catch (InvalidArgumentException $e) {
echo "<p>Ditolak: " . $e->getMessage() . "</p>\n";
}
$jumlah = $db->query("SELECT COUNT(*) FROM pesanan")->fetchColumn();
echo "<p>Pesanan tersimpan: $jumlah</p>\n";