Ini salah satu bug paling licik yang pernah saya temui di WordPress, dan butuh lebih dari empat hari sebelum saya sadar penyebabnya. Di sebuah situs editorial yang saya bangun, sebuah halaman panduan menyimpan daftar bab sebagai JSON di post meta. Suatu hari, daftarnya berhenti tampil — bukan error, bukan halaman putih, hanya "0 item" padahal datanya jelas-jelas ada di database.
Yang bikin pusing: ukuran baris di database tetap sama (datanya masih ada, sekitar segitu besarnya), tapi json_decode() mengembalikan null. Jadi sepertinya data ada tapi tidak bisa dibaca.
Penyebabnya bikin saya ingin membenturkan kepala ke meja: update_post_meta membuang backslash dari JSON Anda.
Kenapa ini terjadi
update_post_meta() (dan saudara-saudaranya) menjalankan wp_unslash() pada nilai secara internal sebelum menyimpan. Bagi data biasa ini tidak masalah. Tapi wp_json_encode() menghasilkan string yang bergantung pada backslash:
\n(newline ter-escape) →wp_unslashmengubahnya jadin\"(kutip ter-escape) → menjadi"— yang langsung merusak struktur JSON\t,\/,\uXXXX→ semua ikut rusak
Hasilnya: string yang tersimpan bukan JSON valid lagi. json_decode menyerah dan mengembalikan null, sehingga template Anda merender nol item. Dan karena ukuran datanya nyaris tidak berubah, Anda tidak akan curiga ke arah "data terpotong".
Begini cara memastikannya — bandingkan apa yang Anda kirim vs apa yang tersimpan:
$data = [ 'judul' => 'Bab "Satu"', 'isi' => "baris1\nbaris2" ];
update_post_meta( $pid, 'daftar_bab', wp_json_encode( $data ) );
$tersimpan = get_post_meta( $pid, 'daftar_bab', true );
var_dump( json_decode( $tersimpan, true ) ); // null ← rusakPerbaikannya: satu baris
Bungkus output wp_json_encode dengan wp_slash() sebelum menyimpan. Ini "menambah" backslash ekstra yang nanti dibuang wp_unslash internal — sehingga JSON Anda sampai ke database dalam keadaan utuh:
update_post_meta( $pid, 'daftar_bab', wp_slash( wp_json_encode( $data ) ) );Itu saja. wp_slash + wp_unslash internal saling meniadakan, dan JSON Anda tersimpan persis seperti yang Anda buat.
Yang penting: bukan cuma update_post_meta
Ini jebakan yang sama di beberapa fungsi WordPress yang menjalankan wp_unslash internal. Hafalkan daftar ini:
| Fungsi | Kena bug slash? |
|---|---|
update_post_meta / add_post_meta | Ya — butuh wp_slash |
update_term_meta / update_user_meta | Ya — butuh wp_slash |
update_option | Ya — butuh wp_slash |
wp_insert_post (untuk post_content) | Tidak — jalur kode berbeda, jangan di-slash |
set_theme_mod / get_theme_mod | Tidak — aman tanpa slash |
Perhatikan dua baris terakhir: kalau Anda ikut menambahkan wp_slash ke post_content atau theme_mod, Anda malah membuat masalah kebalikannya — backslash ekstra yang bocor ke output. Jadi aturannya bukan "selalu slash", tapi "slash hanya pada fungsi yang meng-unslash".
Pelajaran
php -l lolos. Tidak ada error di log. Datanya "ada". Tapi diam-diam rusak selama berhari-hari karena WordPress mengutak-atik nilai Anda di belakang layar. Kalau Anda menyimpan JSON (atau apa pun yang bergantung pada backslash) lewat metadata/option API, selalu wp_slash output wp_json_encode — dan verifikasi dengan json_decode setelah menyimpan, bukan cuma sebelum.
