WordPress melepaskan strip backslash dari string JSON di post_meta

11

Saya pikir saya membuat hidup saya mudah dan sadar akan masa depan dengan menyimpan beberapa konten sebagai bit JSON di bidang post_meta khusus. Sayangnya, WordPress tidak setuju dan membuat hidup saya sangat sulit.

Saya memiliki string JSON yang pada dasarnya terlihat seperti ini. Ini hanya satu bit, dan string komentar hanyalah beberapa entitas unicode dummy. Semuanya dibuat w / json_encode .

{
    "0": {
        "name": "Chris",
        "url": "testdomain.com",
        "comment": "\u00a5 \u00b7 \u00a3 \u00b7 \u20ac \u00b7 \u00b7 \u00a2 \u00b7 \u20a1 \u00b7 \u20a2 \u00b7 \u20a3 \u00b7 \u20a4 \u00b7 \u20a5 \u00b7 \u20a6 \u00b7 \u20a7 \u00b7 \u20a8 \u00b7 \u20a9 \u00b7 \u20aa \u00b7 \u20ab \u00b7 \u20ad \u00b7 \u20ae \u00b7 \u20af \u00b7 \u20b9"
    }
}

Sayangnya setelah saya simpan update_post_meta, hasilnya tampak seperti ini:

{
    "0": {
        "name": "Chris",
        "url": "testdomain.com",
        "comment": "u00a5 u00b7 u00a3 u00b7 u20ac u00b7 u00b7 u00a2 u00b7 u20a1 u00b7 u20a2 u00b7 u20a3 u00b7 u20a4 u00b7 u20a5 u00b7 u20a6 u00b7 u20a7 u00b7 u20a8 u00b7 u20a9 u00b7 u20aa u00b7 u20ab u00b7 u20ad u00b7 u20ae u00b7 u20af u00b7 u20b9"
    }
}

Dan dengan garis miring dilepaskan, itu tidak dapat json_decoded kembali ke konten yang bermanfaat.

Adakah ide mengapa WordPress mungkin melakukan ini, dan jika ada cara untuk menghindarinya? Saya tidak dapat menggunakan flag JSON_UNESCAPED_UNICODE karena ini adalah pemasangan PHP 5.3.x, dan saya sudah mencoba melakukan enkode htmlentitiessebelum konten diteruskan json_encode, tetapi itu hanya menangkap sebagian kecil entitas UTF-8.

Terima kasih sebelumnya!

(EDIT: FWIW, saya tahu saya bisa menyimpan array langsung ke post_meta dan itu akan diserialkan dan sihir akan terjadi tetapi saya hanya suka gagasan memiliki data yang disimpan sebagai JSON. Jika tidak ada solusi yang mudah dan elegan aku akan gua, tapi aku sangat berharap ada adalah solusi yang mudah, elegan!)

Chris Van Patten
sumber

Jawaban:

8

Sepertinya tidak ada cara untuk menghindarinya.

Fungsi update_metadata (), yang bertanggung jawab untuk menyimpan meta, secara eksplisit menjalankan stripslashes_deep () pada nilai meta. Fungsi ini bahkan akan menghapus garis miring dari elemen array, jika nilainya adalah array.

Ada filter yang menjalankan SETELAH yang disebut sanitize_meta, yang dapat Anda hubungi. Tetapi pada saat itu, garis miring Anda telah dilucuti, sehingga Anda tidak dapat menentukan dengan tepat di mana mereka harus ditambahkan kembali (atau setidaknya, saya tidak tahu bagaimana Anda akan mengatakan perbedaan antara mengutip pembatas JSON yang sah vs bit nilai-nilai).

Tidak dapat berbicara mengapa hal ini terjadi, tetapi hal itu terjadi. Mungkin karena itu akhirnya dijalankan melalui pembaruan wpdb->, yang membutuhkan string tidak terhapus.

Seperti yang Anda takutkan, Anda mungkin lebih baik menyimpan nilai sebagai array, yang akan diserialisasi (seperti yang Anda katakan). Jika Anda menginginkannya sebagai JSON nanti, Anda bisa menjalankannya melalui json_encode ().

MathSmath
sumber
Saya takut akan hal itu, tetapi senang mengetahui mengapa itu terjadi. Terima kasih banyak atas tanggapan cepatnya!
Chris Van Patten
Ini tidak benar, lihat jawaban lain :)
jave.web
@ jave.web Memang benar bahwa Anda tidak dapat menghindari memiliki update_metadata () menjalankan garis miring pada string Anda. Jawaban lain memberikan solusi (sangat cerdas) pada dasarnya "meloloskan diri" string Anda, sehingga pengupasan yang tidak terhindarkan menghilangkan garis miring ekstra tersebut tetapi membiarkan garis miring asli Anda tetap utuh. Saya pribadi masih mengatakan bahwa cara "elegan" untuk menangani ini adalah dengan hanya menyimpan data dalam sebuah array, yang tidak memerlukan penanganan khusus atau pra-format. Kemudian konversikan ke json jika dan ketika Anda perlu. Tapi itu hanya kesukaan saya.
MathSmath
25

Ada cara yang elegan untuk menangani ini!

Lewati string yang dikodekan JSON wp_slash(). Fungsi itu akan lolos dari garis miring utama dari setiap karakter unicode yang disandikan, yang akan mencegah update_metadata()pengupasan mereka.

Jereere
sumber
Ini adalah solusi untuk bug Wordpress yang serius. Terima kasih banyak!
netAction
2
Ini harus menjadi jawaban yang diterima. Saya mengalami masalah dengan konten yang diimpor dari GitHub melalui wp_insert_post di mana ini merupakan masalah besar menghapus garis miring dari sampel kode. Menjalankan string melalui wp_slash sebelum mengirimnya melalui wp_insert_post berhasil. Terima kasih!
Matt Keys
Ini masih berguna bahkan sampai hari ini, saya kehilangan waktu untuk menemukan solusi untuk ini tanpa petunjuk sampai saya menemukan ini. Jika Anda ingin menambahkan respons ini pada pertanyaan saya di sini: stackoverflow.com/questions/61091853/... Saya akan menandainya sebagai jawaban yang benar. Terima kasih banyak!
Jaypee
4

Anda dapat menyontek ke wordpress dengan sesuatu seperti ini:

$cleandata = str_replace('\\', '\\\\', json_encode($customfield_data, true));

Ini adalah yang mudah * solusi elegan * ...

drmartin
sumber
+1 Ini melakukan trik untuk situasi saya. itu sedikit berbeda dari OP, tetapi serupa.
Adam Spriggs
2

Fungsi ini melakukan transformasi menggunakan preg_replace:

function preg_replace_add_slash_json($value) {
    return preg_replace('/(u[0-9a-fA-F]{4})/i', '\\\$1', $value);
}

Sebelum setiap urutan "uXXXX" (X = 0..F, heksadesimal) ia menambahkan garis miring terbalik. Sebelum mengirimkan ke DB, panggil fungsi ini.

Florin Chis
sumber
1

Cara menarik tentang ini adalah untuk menyandikan ke base64 lihat contoh di bawah.

$data = Array(0 => array('name' => 'chris' , 'URL' => "hello.com"));

$to_json = json_encode($data);

echo $to_json  . "<br />";
//echos [{"name":"chris","URL":"hello.com"}] 

$to_base64 =  base64_encode($to_json);

Echo $to_base64 . "<br />";
//echos W3sibmFtZSI6ImNocmlzIiwiVVJMIjoiaGVsbG8uY29tIn1d

$back_to_json =  base64_decode($to_base64);

Echo $back_to_json . "<br />";
//echos [{"name":"chris","URL":"hello.com"}]

$back_to_aray = json_decode($back_to_json);

print_r($back_to_aray) ;
//echos  Array ( [0] => stdClass Object ( [name] => chris [URL] => hello.com ))
David Allen
sumber
1

Bagi siapa pun yang masih berjuang dengan menyimpan string unicode json yang disandikan melalui wp_update_post , berikut ini bekerja untuk saya. Ditemukan di class-wp-rest-posts-controller.php

// convert the post object to an array, otherwise wp_update_post will expect non-escaped input.
wp_update_post( wp_slash( (array) $my_post ) ); 

Ini sebuah contoh:

$objectToEncodeToJson = array(
  'my_custom_key' => '<div>Here is HTML that will be converted to Unicode in the db.</div>'
);

$postContent = json_encode($objectToEncodeToJson,JSON_HEX_TAG|JSON_HEX_QUOT);

$my_post = array(
  'ID'           => $yourPostId,
  'post_content' => $postContent
);

wp_update_post( wp_slash( (array) $my_post ) );
gbones
sumber
-1

Anda dapat menggunakan fungsi WordPress stripslashes_deep ().

<?php stripslashes_deep($your_json);?>

Untuk referensi kunjungi di sini

Irfan Bin Hakim
sumber
BARBJANE'smasih dikirim dari WordPress seolahBARBJANE\'s
olah