WordPress elimină backslash-urile de escape din șirurile JSON în post_meta

25 mai 2012, 23:39:35
Vizualizări: 15.4K
Voturi: 19

Am crezut că îmi fac viața mai ușoară și că sunt orientat spre viitor salvând unele conținuturi ca fragmente JSON în câmpuri personalizate post_meta. Din păcate, WordPress nu este de acord și îmi face viața incredibil de dificilă.

Am un șir JSON care arată în esență așa. Acesta este doar un fragment, iar șirul de comentarii este doar niște entități Unicode de exemplu. Totul este generat cu 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"
    }
}

Din păcate, după ce îl salvez cu update_post_meta, iese arătând astfel:

{
    "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"
    }
}

Și cu backslash-urile eliminate, nu mai poate fi decodat înapoi în conținut util cu json_decode.

Idei de ce ar face WordPress asta și dacă există vreo metodă de a evita problema? Nu pot folosi flag-ul JSON_UNESCAPED_UNICODE pentru că folosesc PHP 5.3.x, și am încercat deja codificarea cu htmlentities înainte ca conținutul să fie transmis la json_encode, dar asta captează doar o mică parte din entitățile UTF-8.

Mulțumesc anticipat!

(EDIT: Pentru cei interesați, știu că aș putea salva direct un array în post_meta și ar fi serializat și magia s-ar întâmpla, dar îmi place ideea de a avea datele stocate ca JSON. Dacă nu există o soluție ușoară și elegantă, voi ceda, dar sper foarte mult să existe o astfel de soluție!)

0
Toate răspunsurile la întrebare 8
5
36

Există o modalitate elegantă de a gestiona acest lucru!

Trimite șirul codificat JSON prin wp_slash(). Această funcție va escapa slash-ul principal al fiecărui caracter unicode codificat, ceea ce va preveni update_metadata() să le elimine.

9 ian. 2014 19:20:40
Comentarii

Acesta este o soluție temporară pentru o problemă gravă din WordPress. Mulțumesc mult!

netAction netAction
7 iun. 2017 10:18:55

Acesta ar trebui să fie răspunsul acceptat. Am avut probleme cu conținutul importat din GitHub prin wp_insert_post, unde aceasta a fost o problemă majoră care elimina slash-urile din mostrele de cod. Executarea șirului prin wp_slash înainte de a-l trimite prin wp_insert_post a rezolvat problema. Mulțumesc!

Matt Keys Matt Keys
17 nov. 2017 21:21:05

Acest lucru este încă util chiar și astăzi, am pierdut ore întregi încercând să găsesc o soluție pentru aceasta fără niciun indiciu până când am găsit acest răspuns. Dacă doriți să adăugați acest răspuns la întrebarea mea de aici: https://stackoverflow.com/questions/61091853/wordpress-breaking-unicodes-when-saving-data îl voi marca ca răspuns corect. Mulțumesc foarte mult!

Jaypee Jaypee
8 apr. 2020 07:02:54

Cine ar fi crezut că un post vechi de 8 ani m-ar putea ajuta. Aveam probleme la salvarea blocurilor serializate (Gutenberg), cu atribute codate în JSON care își pierdeau slash-urile. Am rezolvat rulând rezultatul funcției serialize_block prin wp_slash.

Wouter van Vliet Wouter van Vliet
5 apr. 2021 16:47:09

Zece ani mai târziu, am întâmpinat aceeași problemă folosind wp_insert_post(), iar acest lucru mi-a salvat ziua. Mulțumesc!

Saulo Padilha Saulo Padilha
11 iun. 2024 01:08:23
3
11

Se pare că nu există nicio modalitate de a evita acest lucru.

Funcția update_metadata(), care în final este responsabilă pentru salvarea metadatelor, execută în mod explicit un stripslashes_deep() asupra valorii meta. Această funcție va elimina slash-urile chiar și din elementele de tip array, dacă valoarea ar fi un array.

Există un filtru care rulează DUPĂ aceea, numit sanitize_meta, la care te-ai putea conecta. Dar în acel moment, slash-urile tale au fost deja eliminate, așa că nu poți determina în mod fiabil unde trebuiau readăugate (sau cel puțin, nu știu cum ai putea face diferența între ghilimelele legitime JSON și fragmente de valori).

Nu pot spune de ce face acest lucru, dar o face. Probabil pentru că în final este rulat prin wpdb->update, care are nevoie de șirurile de caractere fără escape.

După cum te temeai, probabil că e mai bine să stochezi valoarea ca un array, care va fi serializat (cum ai menționat). Dacă vei avea nevoie de ea ca JSON mai târziu, poți să o trimiți prin json_encode().

26 mai 2012 00:18:44
Comentarii

Mi-era teamă de asta, dar e bine să știu de ce se întâmplă. Mulțumesc mult pentru răspunsul rapid!

Chris Van Patten Chris Van Patten
26 mai 2012 00:33:10

Asta nu este adevărat, vezi și alte răspunsuri :)

jave.web jave.web
6 mar. 2015 16:51:07

@jave.web Este adevărat că nu poți evita ca funcția update_metadata() să elimina backslash-urile din șirul tău. Celelalte răspunsuri oferă soluții (foarte inteligente) pentru a "dubla" backslash-urile, astfel încât eliminarea inevitabilă să înlăture acele backslash-uri suplimentare, dar să lase backslash-urile originale intacte. Personal, aș spune că modul "elegant" de a gestiona această situație este să stochezi datele într-un array, care nu necesită manipulare specială sau preformatare. Apoi să le convertești în json doar atunci când ai nevoie. Dar asta este doar preferința mea.

MathSmath MathSmath
6 mai 2015 21:36:28
1

Puteți păcăli WordPress cu ceva de genul acesta:

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

Aceasta este o soluție simplă și *elegantă*...

1 aug. 2012 13:36:28
Comentarii

+1 Aceasta a funcționat în situația mea. A fost puțin diferită față de OP, dar similară.

Adam Spriggs Adam Spriggs
1 aug. 2018 14:43:16
0

Această funcție realizează transformarea folosind preg_replace:

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

Înainte de fiecare secvență "uXXXX" (X=0..F, hexazecimal) adaugă backslash. Apelați această funcție înainte de trimiterea în baza de date.

19 ian. 2017 12:04:27
0

Pentru cei care încă se confruntă cu salvarea unui șir Unicode codificat JSON prin wp_update_post, următoarea soluție a funcționat pentru mine. Am găsit-o în class-wp-rest-posts-controller.php

// convertește obiectul post într-un array, altfel wp_update_post va aștepta intrare ne-escape-uită.
wp_update_post( wp_slash( (array) $my_post ) ); 

Iată un exemplu:

$objectToEncodeToJson = array(
  'my_custom_key' => '<div>Aici este HTML care va fi convertit în Unicode în baza de date.</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 ) );
8 mar. 2019 22:38:58
0

O metodă interesantă de a rezolva această problemă este codificarea în base64, conform exemplului de mai jos.

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

$to_json = json_encode($data);

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

$to_base64 =  base64_encode($to_json);

Echo $to_base64 . "<br />";
//afișează W3sibmFtZSI6ImNocmlzIiwiVVJMIjoiaGVsbG8uY29tIn1d

$back_to_json =  base64_decode($to_base64);

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

$back_to_aray = json_decode($back_to_json);

print_r($back_to_aray) ;
//afișează Array ( [0] => stdClass Object ( [name] => chris [URL] => hello.com ))
18 iun. 2013 14:34:16
0

Știu că aceasta este o întrebare veche, dar încă este o problemă care afectează dezvoltatorii astăzi. Așadar, ca referință, iată un subiect util din trackerul de probleme al nucleului WordPress pe care l-am găsit informativ: https://core.trac.wordpress.org/ticket/21767

21 mai 2024 14:54:55
1
-1

Puteți utiliza funcția WordPress stripslashes_deep().

<?php stripslashes_deep($your_json);?>

Pentru referință vizitați aici

25 ian. 2017 09:49:31
Comentarii

BARBJANE's este în continuare trimis din WordPress ca BARBJANE\'s dacă nu greșesc eu cu ceva aici...

Si8 Si8
10 apr. 2018 23:38:59