Skip to content

Ikhtisar Chapter 26: Custom SQL Database Table

Apa yang Dipelajari?

Kapan dan bagaimana membuat custom database table sendiri di WordPress — sebagai alternatif Custom Post Type ketika butuh query cepat pada data berjumlah besar, lengkap dengan CRUD (Create, Read, Update, Delete) dari front-end.


Poin Utama

1. Kapan Butuh Custom Table?

Custom Post Type cocok untuk 9 dari 10 kasus karena WordPress memberikan gratis: admin UI, REST API, permissions, dll.

Custom table dibutuhkan hanya jika dua kondisi terpenuhi sekaligus:

  • Perlu query berdasarkan metadata (filter, sort, search)
  • Jumlah data sangat besar (ribuan hingga ratusan ribu)
SkenarioCustom Post TypeCustom Table
Query dasar (100 data)~0.2 detik~0.1 detik
Query + filter metadata~1.2 detik~0.1 detik

Penyebab lambat: di CPT, setiap property custom tersimpan sebagai row terpisah di wp_postmeta (1 pet × 6 property = 6 rows). Custom table menyimpan semua di 1 row.


2. Membuat Tabel dengan dbDelta

Tabel dibuat saat plugin diaktifkan (register_activation_hook):

php
dbDelta("CREATE TABLE {$tableName} (
    id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
    petname varchar(60) NOT NULL DEFAULT '',
    species varchar(60) NOT NULL DEFAULT '',
    ...
    PRIMARY KEY  (id)
) {$charset};");

Aturan ketat dbDelta():

  • Setiap kolom di baris sendiri
  • Dua spasi antara PRIMARY KEY dan (id)
  • Tidak ada koma setelah item terakhir

Keunggulan: dbDelta aman dijalankan ulang — hanya menerapkan perubahan (delta), tidak menghapus data.


3. Query Data & Keamanan SQL

MethodFungsi
$wpdb->get_results()Ambil banyak row (array of objects)
$wpdb->get_var()Ambil satu nilai (misal COUNT)
$wpdb->prepare()Wajib untuk mencegah SQL injection

Placeholder di prepare(): %s untuk string, %d untuk angka.

php
$wpdb->prepare("SELECT * FROM $table WHERE species = %s AND birthyear > %d", ['cat', 2018]);

4. Dynamic Query Builder (Class GetPets)

Class GetPets menerima URL parameter (seperti ?species=dog&minweight=20) dan membangun SQL secara dinamis:

URL parameter → getArgs() (sanitize) → createWhereText() → specificQuery() → $wpdb->prepare() → execute

Keamanan berlapis:

  1. isset() → cek parameter ada
  2. sanitize_text_field() → bersihkan input
  3. $wpdb->prepare() → escape SQL injection
  4. Hanya terima parameter yang diharapkan — abaikan sisanya

5. Create & Delete dari Front-End

Menggunakan admin-post.php sebagai handler form:

AksiHookMethod
Tambahadmin_post_create_pet$wpdb->insert($table, $data)
Hapusadmin_post_delete_pet$wpdb->delete($table, ['id' => $id])

Keamanan:

  • current_user_can('administrator') → cek di PHP (jangan hanya di HTML)
  • sanitize_text_field() → bersihkan input
  • wp_safe_redirect() → redirect hanya ke URL lokal
  • exitwajib setelah redirect

6. Konversi ke Block Type

Plugin bisa diubah jadi block type agar bisa disisipkan di editor:

  • registerBlockType() → tampilkan placeholder di editor
  • render_callback + ob_start/ob_get_clean → render PHP di front-end
  • Class OurPluginPlaceholderBlock → reusable untuk banyak block

Satu Kalimat

Chapter ini mengajarkan kapan dan bagaimana membuat custom database table untuk data besar yang sering di-query, lengkap dengan dynamic query builder, keamanan SQL berlapis, dan CRUD dari front-end.