Modul penutup jalur ini mengerjakan sebuah proyek kecil secara utuh, dan langkah pertamanya adalah perencanaan. Topik ini menyusun rencana untuk aplikasi web mini “Daftar Tugas”, yaitu pengelola tugas pribadi satu pengguna yang menampilkan daftar tugas, menambah tugas melalui form, menandai tugas selesai, dan menghapus tugas. Lingkup ditetapkan lebih dahulu, kemudian skema basis data dirancang, daftar periksa keamanan disusun, dan struktur berkas proyek ditetapkan. Aplikasi yang direncanakan di sini dibangun pada topik Implementasi dan diperiksa ulang pada topik Penguatan dan Tinjauan. Setiap keputusan pada topik ini dipakai kembali pada kedua topik tersebut.
Lingkup proyek#
Lingkup proyek adalah batas antara fitur yang dibangun dan fitur yang sengaja ditinggalkan, dan batas itu ditetapkan sebelum kode pertama ditulis. Aplikasi Daftar Tugas dimaksudkan sebagai aplikasi mini yang tuntas dikerjakan dalam satu modul, sehingga setiap fitur yang tidak menopang inti aplikasi ditunda. Tabel berikut memuat keputusannya beserta alasannya.
| Fitur | Keputusan | Alasan |
|---|---|---|
| Menampilkan daftar tugas | Masuk lingkup | Fitur inti yang menjadi dasar tiga fitur lainnya |
| Menambah tugas melalui form | Masuk lingkup | Satu-satunya pintu masukan data |
| Menandai tugas selesai | Masuk lingkup | Mengubah kolom selesai menjadi 1 |
| Menghapus tugas | Masuk lingkup | Melengkapi siklus hidup satu tugas |
| Login multi-pengguna | Dikeluarkan | Aplikasi satu pengguna lokal sehingga tidak ada kata sandi yang dikelola |
| Pendaftaran pengguna | Dikeluarkan | Menyertai login yang dikeluarkan |
| Unggah berkas | Dikeluarkan | Memperluas permukaan keamanan tanpa menyinggung fitur inti |
| Kategori dan prioritas | Dikeluarkan | Dapat ditambahkan kemudian tanpa mengubah desain inti |
Keputusan yang paling menentukan adalah ketiadaan login. Aplikasi ini berjalan sebagai aplikasi satu pengguna pada komputer lokal, sehingga tidak ada kata sandi yang perlu di-hash dan diverifikasi. Fungsi password_hash dari modul Keamanan dengan demikian tidak dipakai pada proyek ini. Batasan tersebut dinyatakan eksplisit agar lingkup tetap kecil, karena menambahkan login berarti menambahkan pendaftaran, pembedaan data antarpengguna, dan halaman terproteksi yang semuanya berada di luar kebutuhan inti.
Empat fitur yang masuk lingkup tetap melatih seluruh kemampuan yang dibahas jalur ini, yaitu akses basis data, penanganan form, keamanan keluaran, dan pemisahan kode. Setiap fitur yang dikeluarkan memiliki alasan yang tercatat, sehingga keputusannya dapat ditinjau ulang dengan dasar yang jelas apabila proyek diperbesar kelak.
Skema basis data#
Skema menetapkan bentuk data sebelum baris pertama disimpan, dan aplikasi Daftar Tugas hanya memerlukan satu tabel bernama tugas. Tabel itu berisi empat kolom, yaitu id sebagai pengenal baris, judul sebagai isi tugas, selesai sebagai status, dan dibuat_pada sebagai penanda waktu pembuatan. Skrip berikut membuat tabel tersebut pada basis data di memori, lalu membaca kembali strukturnya melalui PRAGMA table_info, yaitu perintah SQLite yang mengembalikan satu baris untuk setiap kolom.
<?php
declare(strict_types=1);
// pratinjau skema tabel tugas pada basis data di memori
$pdo = new PDO('sqlite::memory:', null, null, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
$pdo->exec('CREATE TABLE tugas (
id INTEGER PRIMARY KEY AUTOINCREMENT,
judul TEXT NOT NULL,
selesai INTEGER NOT NULL DEFAULT 0,
dibuat_pada TEXT NOT NULL
)');
echo "cid|nama|tipe|notnull|default|pk\n";
foreach ($pdo->query('PRAGMA table_info(tugas)') as $kolom) {
printf(
"%d|%s|%s|%d|%s|%d\n",
$kolom['cid'],
$kolom['name'],
$kolom['type'],
$kolom['notnull'],
$kolom['dflt_value'] ?? '',
$kolom['pk']
);
}cid|nama|tipe|notnull|default|pk
0|id|INTEGER|0||1
1|judul|TEXT|1||0
2|selesai|INTEGER|1|0|0
3|dibuat_pada|TEXT|1||0Keluaran di atas memerincikan keempat kolom beserta sifatnya. Kolom id bertipe INTEGER dengan PRIMARY KEY AUTOINCREMENT, sehingga SQLite menaikkan nilainya sendiri untuk setiap baris baru dan tidak ada kode aplikasi yang perlu menghitungnya. Kolom selesai bertipe INTEGER dengan nilai 0 dan 1 karena SQLite tidak memiliki tipe boolean terpisah, sedangkan DEFAULT 0 membuat tugas baru selalu berstatus belum selesai tanpa pernyataan tambahan. Kolom dibuat_pada bertipe TEXT dengan format Y-m-d H:i:s mengikuti ISO 8601, dan format tersebut membuat urutan teksnya sama dengan urutan waktunya.
Daftar periksa keamanan#
Daftar periksa keamanan memetakan setiap ancaman yang relevan ke tindakan pencegahan yang konkret, dan daftar ini disusun sebelum kode ditulis. Pertahanan yang dipikirkan sejak awal menjadi bagian dari desain, sedangkan pertahanan yang ditambahkan belakangan cenderung tersebar di banyak titik dan mudah terlewat. Aplikasi menerima masukan dari form lalu mencetaknya kembali, sehingga kelima ancaman berikut relevan meskipun aplikasinya kecil.
| Ancaman | Tindakan pada implementasi |
|---|---|
| XSS | Setiap keluaran dinamis dilewatkan htmlspecialchars dengan ENT_QUOTES dan UTF-8 |
| SQL injection | Seluruh query memakai prepared statement dengan parameter terikat |
| CSRF | Token acak disimpan per sesi di $_SESSION, dibawa form sebagai input tersembunyi, dan diverifikasi dengan hash_equals |
| Manipulasi parameter id | id diperiksa dengan filter_var dan FILTER_VALIDATE_INT sebelum dikirim sebagai parameter terikat |
| Pencurian isi session | Cookie session ditandai httponly dan samesite Lax sebelum session_start |
Kelima tindakan di atas memakai pertahanan yang masing-masing sudah dibahas mendalam pada modul Keamanan, mulai dari htmlspecialchars, prepared statement, token CSRF, hingga keamanan session. Yang berbeda pada proyek ini adalah penggabungan kelima pertahanan itu menjadi satu kesatuan, karena setiap pertahanan harus terpasang pada titik yang tepat dalam satu alur permintaan yang sama. Daftar ini juga menjadi instrumen pemeriksaan, karena topik Penguatan dan Tinjauan memeriksa kembali setiap barisnya terhadap kode yang sudah jadi.
Struktur berkas proyek#
Struktur berkas menentukan letak setiap tanggung jawab sebelum berkasnya ada. Proyek ini memakai empat berkas yang tersebar dalam tiga folder, dan pohonnya terlihat seperti berikut.
proyek-tugas/
├── public/
│ └── index.php
├── src/
│ └── TugasRepository.php
├── templates/
│ └── daftar.php
└── skema.phpPeran setiap berkas dirangkum sebagai berikut.
public/index.php: satu-satunya berkas yang dilayani server. Berkas ini membaca permintaan, memverifikasi token CSRF pada aksi tulis, memanggil repository, lalu menyerahkan data ke template. Urutan itu adalah pola front controller dari modul Pola Aplikasi Web dalam bentuknya yang paling sederhana.src/TugasRepository.php: kelas repository, yaitu kelas yang memusatkan seluruh akses data. Tidak ada berkas lain yang menulis query.templates/daftar.php: berisi HTML beserta pelolosan keluarannya. Template hanya mencetak data yang diberikan dan tidak mengambil data sendiri.skema.php: menyiapkan basis data demo sebelum server dijalankan.
Folder public memuat satu-satunya berkas yang boleh dijangkau URL, sedangkan src dan templates berada di luar jangkauan itu. Pada server produksi, folder dokumen diarahkan ke public, sehingga kode internal tidak pernah terkirim ke browser meskipun ada permintaan yang mencoba menebak jalur berkas internal. Pada proyek nyata, pemuatan berkas kelas secara manual digantikan autoloader Composer sebagaimana dibahas modul Namespace, Composer, dan PSR.
Ringkasan#
- Lingkup proyek memuat empat fitur inti, sedangkan login multi-pengguna, pendaftaran, unggah berkas, serta kategori dikeluarkan dengan alasan yang dicatat.
- Skema terdiri atas satu tabel
tugasdengan kolomid,judul,selesaibernilai 0 atau 1, dandibuat_padaberformat ISO 8601. - Daftar periksa keamanan memetakan lima ancaman ke tindakan konkret, yaitu
htmlspecialchars, prepared statement, token CSRF per sesi, pemeriksaanid, dan cookie session bertandahttponly. - Struktur berkas memisahkan titik masuk publik, repository, template, dan skrip skema.
Referensi#
- PDO — PHP Manual — Dokumentasi ekstensi PDO yang dipakai seluruh akses basis data pada proyek ini.
- SQLite (PDO) — PHP Manual — Menjelaskan DSN khusus driver SQLite, baik basis data berkas maupun basis data di memori.
- Databases — PHP The Right Way — Bagian basis data yang menyinggung pemilihan PDO dan penanganan nilai dari pengguna.
- OWASP Cheat Sheet Series — OWASP — Kumpulan lembar panduan keamanan yang menjadi rujukan daftar periksa pada topik ini.