D
P
0

WordPress & Elementor

update_post_meta Diam-Diam Merusak JSON Anda (dan Data Hilang Berhari-hari)

16 Juni 2026·2 menit baca
update_post_meta Diam-Diam Merusak JSON Anda (dan Data Hilang Berhari-hari)

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_unslash mengubahnya jadi n
  • \" (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  ← rusak

Perbaikannya: 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:

FungsiKena bug slash?
update_post_meta / add_post_metaYa — butuh wp_slash
update_term_meta / update_user_metaYa — butuh wp_slash
update_optionYa — butuh wp_slash
wp_insert_post (untuk post_content)Tidak — jalur kode berbeda, jangan di-slash
set_theme_mod / get_theme_modTidak — 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.